Cassandra:批量写入优化

11

我从客户端获取了一批写入请求,假设是 20 个键。 我可以将它们作为一个批次写入 C*,也可以异步地单独写入每个键,并等待 future 完成。

根据文档,批量写入似乎不是一个好的选择,因为我的插入速率很高,如果这些键属于不同的分区,则协调器将不得不做额外的工作。

在 datastax java 驱动程序中是否有一种方法,可以将可能属于同一分区的键分组,然后将它们组合成小批量,在异步方式下逐个写入而不需要记录日志。这样可以减少向服务器发出的 RPC 调用,同时协调器只需在本地写入。我将使用 token aware 策略。

2个回答

11

您的想法是正确的,但没有内置的方法,通常需要手动操作。

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

我所说的“按分区键相等性分组”的意思是,例如您有一些数据看起来像:

MyData { partitioningKey, clusteringKey, otherValue, andAnotherOne }

当插入多个这样的对象时,您需要通过 MyData.partitioningKey 对它们进行分组。也就是说,对于所有现有的partitioningKey值,您需要取出所有具有相同partitioningKey的对象,并将它们包装在BatchStatement中。现在您有了多个BatchStatements,只需执行它们即可。

如果您希望更进一步地模拟Cassandra哈希,则应查看com.datastax.driver.core.Cluster类中的getMetadata方法来获取集群元数据,其中有一个getTokenRanges方法,将其与Murmur3Partitioner.getToken或您在cassandra.yaml中配置的任何其他分区器的结果进行比较。不过我自己从未尝试过这种方法。

因此,我建议首先实现第一种方法,然后对您的应用程序进行基准测试。我自己正在使用这种方法,在我的工作负载上,它比不使用批处理要好得多,更不用说没有分组的批处理了。


如何批量将键分配到同一节点?- 数据堆客户端是否公开属于每个节点的令牌,以便我可以进行 MurmurHash 并将它们分组? - Peter
你能再详细解释一下“你可以通过分区键的相等性来分组请求”这部分吗?我没有理解这个部分。 - Peter
添加了一些细节。 - folex
谢谢,那很有帮助。 - Peter
我认为Hbase驱动程序在内部执行此操作,Datastax应该在批量查询的情况下加以整合。 - Peter

0

Cassandra 中应该谨慎使用 Logged 批处理,因为它们会增加额外的开销。这也取决于分区键的分布。如果您的批量写入目标是单个分区,则使用 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

编辑:
请阅读以下内容: https://inoio.de/blog/2016/01/13/cassandra-to-batch-or-not-to-batch/#14

一个单分区批处理的成本是多少?
对于单分区批处理,没有批处理日志可写。协调器没有额外的工作(对于多分区写入),因为所有内容都进入单个分区。单分区批处理已经优化:它们使用单个RowMutation [10]应用。
简而言之:单分区批处理对服务器的负载不会比普通写入更大。

多分区批处理的成本是多少?

让我引用Christopher Batey的话,因为他在他的帖子“Cassandra反模式:已记录的批处理”[3]中很好地总结了这一点:

Cassandra首先将所有语句写入批处理日志。该批处理日志会被复制到其他两个节点,以防协调器失败。如果协调器失败,则批处理日志的另一个副本将接管。[..]协调器必须比群集中的任何其他节点做更多的工作。

再次列出需要完成的任务:

  1. 序列化批处理语句
  2. 将序列化的批处理写入批处理日志系统表
  3. 将此序列化的批处理复制到2个节点
  4. 协调对持有不同分区的节点的写入
  5. 成功后从批处理日志中删除序列化的批处理(也适用于2个副本)

请记住,自Cassandra 2.1.6以来,针对多个分区的未记录批处理已被弃用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接