问题 Cassandra:批量写入优化


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

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

在datastax java驱动程序中是否有一种方法可以将密钥组合在一起   它可能属于同一个分区,然后将它们分成小块   批处理,然后在异步中执行invidual unlogged batch write。在那里面   方式我会在协调员的同时减少对服务器的rpc调用   必须在本地写。我将使用令牌感知策略。


2942
2017-08-13 10:49


起源



答案:


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

这里的主要规则是使用 TokenAwarePolicy所以在驾驶员方面会发生一些协调。 然后,您可以通过分区键的相等性对请求进行分组,这可能就足够了,具体取决于您的工作负载。

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

MyData { partitioningKey, clusteringKey, otherValue, andAnotherOne }

然后在插入几个这样的对象时,将它们分组 MyData.partitioningKey。对于所有存在而言,它都是存在的 paritioningKey 值,您可以使用相同的所有对象 partitioningKey,并将它们包裹起来 BatchStatement。现在你有几个 BatchStatements,所以只需执行它们。

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

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


9
2017-08-16 12:09



如何批量密钥转到同一节点? - 数据stax客户端是否公开属于每个节点的令牌,所以我可以murmurhash然后将它们分组? - Peter
用编辑回答。 - folex
你可以解释一下“你可以通过分区键的相等性来分组你的请求”吗?我不明白这一部分 - Peter
添加了一些细节。 - folex
谢谢,这有帮助 - Peter


答案:


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

这里的主要规则是使用 TokenAwarePolicy所以在驾驶员方面会发生一些协调。 然后,您可以通过分区键的相等性对请求进行分组,这可能就足够了,具体取决于您的工作负载。

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

MyData { partitioningKey, clusteringKey, otherValue, andAnotherOne }

然后在插入几个这样的对象时,将它们分组 MyData.partitioningKey。对于所有存在而言,它都是存在的 paritioningKey 值,您可以使用相同的所有对象 partitioningKey,并将它们包裹起来 BatchStatement。现在你有几个 BatchStatements,所以只需执行它们。

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

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


9
2017-08-16 12:09



如何批量密钥转到同一节点? - 数据stax客户端是否公开属于每个节点的令牌,所以我可以murmurhash然后将它们分组? - Peter
用编辑回答。 - folex
你可以解释一下“你可以通过分区键的相等性来分组你的请求”吗?我不明白这一部分 - Peter
添加了一些细节。 - folex
谢谢,这有帮助 - Peter


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

一般来说,以异步方式编写它们似乎是一个很好的方法,如下所示: https://medium.com/@foundev/cassandra-batch-loading-without-the-batch-the-nuanced-edition-dd78d61e98​​85

您可以在上面的站点上找到如何处理多个异步写入的示例代码: 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]。

简而言之:单个分区批次不会增加太多负载   服务器比正常写入。


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

让我引用克里斯托弗·贝蒂的话,因为他总结了这一点   非常好的在他的帖子“Cassandra反模式:记录批次”[3]:

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

再次,在子弹中必须做的事情:

  1. 序列化批处理语句
  2. 将序列化批处理写入批处理日志系统表
  3. 将此序列化批次复制到2个节点
  4. 坐标写入持有不同分区的节点
  5. 成功时从批处理日志中删除序列化批处理(也在2个副本上)

请记住,自Cassandra 2.1.6起,不推荐使用多个分区的未记录批次


0
2017-08-17 15:49