Cassandra中的批量限制是什么?

30

我有一个Java客户端,将记录批量推送(INSERT)到Cassandra集群中。批处理中的元素都具有相同的行键,因此它们都将被放置在同一个节点上。另外,我不需要事务是原子的,所以我一直使用未记录的批处理。

每个批处理中的INSERT命令数量取决于不同的因素,但可以是5到50000之间的任意数字。起初,我只是将尽可能多的命令放入一个批处理中并提交。结果出现了com.datastax.driver.core.exceptions.InvalidQueryException: Batch too large错误。然后我将每个批处理的INSERT限制设置为1000,然后降低到300。我注意到我只是随机猜测而不知道这个限制来自哪里,这可能会带来麻烦。

我的问题是,这个限制是什么?我能修改它吗?如何知道有多少元素可以放入批处理中?我的批处理何时“满”?

3个回答

36
我建议不要增加限制,而是将请求分成多个。将所有内容放在一个巨大的单一请求中将会对协调器产生负面影响。将所有内容放在一个分区中可以通过减少某些延迟来提高一些批次的吞吐量,但是批处理从来没有旨在用于提高性能。因此,尝试使用不同的批处理大小来优化以获得最大吞吐量将在很大程度上取决于用例/模式/节点,并且需要特定的测试,因为通常存在开始退化的临界点。

有一个

# Fail any batch exceeding this value. 50kb (10x warn threshold) by default.
batch_size_fail_threshold_in_kb: 50

在您的cassandra.yaml中可以进行调整以增加它,但请务必进行测试以确保确实有所帮助,而不是影响吞吐量。


这正是我在寻找的,谢谢。你知道在客户端监控批处理大小的最佳方法是什么吗? - m.hashemian
2
根据您使用的驱动程序而定,但在java-driver中,您可以在批处理中的每个单独语句上使用getValues(),它会返回一个ByteBuffer数组,您可以使用remaining()方法分别获取缓冲区的大小并将它们总和起来。但是,一般来说,我不建议这样做。您不应该创建超大批次,只需创建足够大的批次即可,并且可以感觉到您远未接近该限制。 - Andy Tolbert
这里有很多东西。C倡导按列设计而不是行,并且C表示每个分区的列数为2B,但我们凭经验知道甜点是100MB。因此,即使使用100MB分区,如果批处理的默认大小为50KB,那么就需要3125个请求来检索100MB分区,这样请求太多了。 - user1870400
批处理在今天仍然需要经过协调器吗?为什么我们不能使用令牌感知策略并将单个分区的所有行(假设所有行的数据大小为100MB)直接批处理到正确的节点?如果不行,检索100MB分区的最佳批处理大小是多少个请求? - user1870400
@user1870400 如果您要检索整个分区,就不需要使用批量查询。只需使用带分页的1个查询即可。如果您正在编写分区,则对我来说,每100MB进行3000个请求是可以接受的。 - user3711864

5

查看Cassandra日志,您将能够发现以下内容:

错误 19:54:13 [matches]的批处理大小为103.072KiB,超过指定的50.000KiB阈值53.072KiB。 (请参阅batch_size_fail_threshold_in_kb)


@user1870400,我正在使用以下配置: cassandra.concurrent.writes=1500 cassandra.output.batch.size.bytes=2056 cassandra.output.batch.grouping.key=partition cassandra.output.consistency.level=ANY cassandra.output.batch.grouping.buffer.size=3000 cassandra.output.throughput_mb_per_sec=25 - BdEngineer
@user1870400,我有2亿条记录,每条记录100字节...加载这些数据需要2小时...那么如何优化上述参数? - BdEngineer

4

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