我试图从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中以高吞吐量加载批量数据的下一个最佳选择是什么?
答案 0 :(得分:2)
正如您所观察到的,单个编写器只能在串行中使用(如果不这样,将发生ConcurrentModificationExceptions),并且由于SSTableWriter使用的Cassandra代码中的静态模式构造,在JVM中创建多个编写器失败。
我不知道除了生成多个JVM之外的任何解决方法,每个JVM都写入一个单独的目录。
我们已经提交了一张Cassandra JIRA票来解决这个问题。