我收到批量写入请求,让我们说来自客户端的大约 20 个密钥。我可以将它们一次性写入 C*,也可以以异步方式单独写入,然后等待将来完成。
根据文档,批量编写似乎不是一个好的选择,因为我的插入率会很高,如果键属于不同的分区,协调员将不得不做额外的工作。
在datastax java驱动程序中是否有一种方法可以将可能属于同一分区的密钥分组,然后将它们分成小批量,然后以异步方式进行单独的未记录批量写入。这样我就可以减少对服务器的 rpc 调用,同时协调器必须在本地写入。我将使用令牌感知策略。
我收到批量写入请求,让我们说来自客户端的大约 20 个密钥。我可以将它们一次性写入 C*,也可以以异步方式单独写入,然后等待将来完成。
根据文档,批量编写似乎不是一个好的选择,因为我的插入率会很高,如果键属于不同的分区,协调员将不得不做额外的工作。
在datastax java驱动程序中是否有一种方法可以将可能属于同一分区的密钥分组,然后将它们分成小批量,然后以异步方式进行单独的未记录批量写入。这样我就可以减少对服务器的 rpc 调用,同时协调器必须在本地写入。我将使用令牌感知策略。
你的想法是对的,但是没有内置的方法,你通常是手动做的。
这里的主要规则是使用TokenAwarePolicy
,因此驾驶员侧会发生一些协调。然后,您可以通过分区键的相等性对您的请求进行分组,这可能就足够了,具体取决于您的工作量。
我所说的“按分区键的相等性分组”的意思是,例如,您有一些看起来像的数据
MyData { partitioningKey, clusteringKey, otherValue, andAnotherOne }
然后在插入几个这样的对象时,将它们分组MyData.partitioningKey
。它是,对于所有现有paritioningKey
值,您将所有具有相同的对象partitioningKey
,并将它们包装在BatchStatement
. 现在你有几个BatchStatements
,所以只需执行它们。
如果您想更进一步并模仿 cassandra 散列,那么您应该通过类中的getMetadata
方法查看集群元数据com.datastax.driver.core.Cluster
,有方法getTokenRanges
并将它们与Murmur3Partitioner.getToken
您配置的结果或任何其他分区器进行比较cassandra.yaml
。不过,我自己从未尝试过。
因此,我建议实施第一种方法,然后对您的应用程序进行基准测试。我自己也在使用这种方法,在我的工作量上,它比没有批处理要好得多,更不用说没有分组的批处理了。
在 Cassandra 中应谨慎使用已记录的批处理,因为它们会带来额外的开销。它还取决于分区键分布。如果您的批量写入针对单个分区,则使用未记录批处理会导致单个插入操作。
一般来说,以异步方式单独编写它们似乎是一个很好的方法,如下所示: https ://medium.com/@foundev/cassandra-batch-loading-without-the-batch-the-nuanced-edition-dd78d61e9885
您可以在上述网站上找到如何处理多个异步写入的示例代码: https ://gist.github.com/rssvihla/26271f351bdd679553d55368171407be#file-bulkloader-java https://gist.github.com/rssvihla/4b62b8e5625a805583c1ce39b1260ff4#file -bulkloader-java
编辑:
另请阅读:
https ://inoio.de/blog/2016/01/13/cassandra-to-batch-or-not-to-batch/#14
单个分区批处理的成本是多少?
没有为单个分区批处理写入批处理日志。协调器没有任何额外的工作(如多分区写入),因为所有内容都进入单个分区。单分区批次进行了优化:它们与单个 RowMutation [10] 一起应用。
简而言之:单分区批处理不会比正常写入给服务器带来更多的负载。
多分区批处理的成本是多少?
让我引用 Christopher Batey 的话,因为他在他的帖子“Cassandra 反模式:记录的批次”[3] 中很好地总结了这一点:
Cassandra [首先] 将所有语句写入批处理日志。如果协调器失败,该批处理日志将复制到其他两个节点。如果协调器失败,则批处理日志的另一个副本将接管。[..] 协调器必须比集群中的任何其他节点做更多的工作。
同样,在项目符号中必须做的事情:
- 序列化批处理语句
- 将序列化的批处理写入批处理日志系统表
- 将此序列化批次复制到 2 个节点
- 协调对持有不同分区的节点的写入
- 成功时从批处理日志中删除序列化批处理(也在 2 个副本上)
请记住,自 Cassandra 2.1.6 以来,不推荐使用多个分区的未记录批处理