同时使用CQLSSTableWriter

时间:2014-06-24 21:48:10

标签: multithreading cassandra bulkinsert apache-spark

我试图从Spark中的批量计算结果创建Cassandra SSTables。理想情况下,每个分区都应为其保存的数据创建SSTable,以便尽可能并行化流程(甚至可能将其流式传输到Cassandra环)

CQLSSTableWriter的最初障碍(就像要求yaml文件)之后,我现在面对这个问题:

java.lang.RuntimeException: Attempting to load already loaded column family customer.rawts
    at org.apache.cassandra.config.Schema.load(Schema.java:347)
    at org.apache.cassandra.config.Schema.load(Schema.java:112)
    at org.apache.cassandra.io.sstable.CQLSSTableWriter$Builder.forTable(CQLSSTableWriter.java:336) 

我在每个并行分区上创建一个编写器,如下所示:

def store(rdd:RDD[Message]) = {
    rdd.foreachPartition( msgIterator => {
      val writer = CQLSSTableWriter.builder()
        .inDirectory("/tmp/cass")
        .forTable(schema)
        .using(insertSttmt).build()
      msgIterator.foreach(msg => {...})
    })}

如果我正确地读取异常,我只能在一个JVM中为每个表创建一个编写器。我想对writer的写作将不是线程安全的,即使它们是多个线程将通过让所有并行任务试图同时将几GB数据转储到磁盘而创建的争论将会失败的目的无论如何都使用SSTable进行批量上传。

那么,是否有同时使用CQLSSTableWriter的方法?

如果没有,在Cassandra中以高吞吐量加载批量数据的下一个最佳选择是什么?

1 个答案:

答案 0 :(得分:2)

正如您所观察到的,单个编写器只能在串行中使用(如果不这样,将发生ConcurrentModificationExceptions),并且由于SSTableWriter使用的Cassandra代码中的静态模式构造,在JVM中创建多个编写器失败。

我不知道除了生成多个JVM之外的任何解决方法,每个JVM都写入一个单独的目录。

我们已经提交了一张Cassandra JIRA票来解决这个问题。

https://issues.apache.org/jira/browse/CASSANDRA-7463