首页 文章

Cassandra:批量写入优化

提问于
浏览
11

我得到批量写入请求,让我们说来自客户端的20个密钥 . 我可以在一个批处理中将它们写入C *,也可以以异步方式单独写入它们并等待将来完成它们 .

批量写入似乎不是一个goo选项,因为我的插入率很高,如果键属于不同的分区,协调员将不得不做额外的工作 .

在datastax java驱动程序中是否有一种方法,我可以使用该方法对可能属于同一分区的密钥进行分组,然后将它们分成小批量,然后在异步中进行不定期的未记录批量写入 . 通过这种方式,我可以减少对服务器的rpc调用,同时协调器必须在本地写入 . 我将使用令牌感知策略 .

2 回答

  • 9

    你的想法是正确的,但没有内置的方式,你通常手动这样做 .

    这里的主要规则是使用 TokenAwarePolicy ,因此在驱动程序端会发生一些协调 . 然后,您可以通过分区键的相等性对请求进行分组,这可能就足够了,具体取决于您的工作负载 .

    我所说的“通过分区密钥的相等性分组”是指例如你有一些看起来像的数据

    MyData { partitioningKey, clusteringKey, otherValue, andAnotherOne }
    

    然后在插入多个这样的对象时,按 MyData.partitioningKey 对它们进行分组 . 对于所有存在的 paritioningKey 值,您将所有对象与 partitioningKey 相同,并将它们包装在 BatchStatement 中 . 现在你有几个 BatchStatements ,所以只需执行它们 .

    如果你想进一步模仿cassandra哈希,那么你应该通过 com.datastax.driver.core.Cluster 类中的 getMetadata 方法查看群集元数据,方法 getTokenRanges 并将它们与 Murmur3Partitioner.getToken 的结果或您在 cassandra.yaml 中配置的任何其他分区进行比较 . 我自己从未尝试过 .

    所以,我建议实施第一种方法,然后对您的应用程序进行基准测试 . 我自己正在使用这种方法,而且在我的工作量方面,它比没有批处理更好,更不用说没有分组的批处理了 .

  • 0

    Logged 批次应该在Cassandra中小心使用,因为它们会产生额外的开销 . 它还取决于分区键分配 . 如果批量写入针对单个分区,则使用 Unlogged 批处理会导致单个插入操作 .

    一般来说,以异步方式编写它们似乎是一个很好的方法,如下所示: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

    EDIT:
    请阅读此内容: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起,不推荐使用多个分区的未记录批次

相关问题