Cassandra 0.7.2是否存在get_range_slices的性能问题?

时间:2011-03-21 02:16:44

标签: performance cassandra batch-processing

我有一个应用程序,它将数十亿条记录写入Cassandra并按密钥删除重复项。然后,它在连续的阶段中通过其他字段(例如标题)对它们进行分组,以便可以对类似记录的组进行进一步处理。该应用程序分布在一组机器上,因为我需要它在合理的时间内完成(几小时而不是几周)。

应用程序的一个阶段是通过使用hector客户端将记录写入Cassandra,并将记录存储在列族中,并将记录的主键作为Cassandra键存储。时间戳设置为记录的最后更新日期,以便我只获取每个密钥的最新记录。

后期阶段需要从Cassandra读取所有内容,对记录执行一些处理,并使用各种其他键将记录添加回不同的列族,以便记录可以分组。

我通过使用Cassandra.Client.describe_ring()来完成批量读取,以确定环中哪台机器是TokenRange的主机。然后,我将每个TokenRange的主服务器与localhost进行比较,以找出本地计算机拥有哪些令牌范围(远程读取对于这种类型的批处理来说太慢)。一旦我知道本地每台机器上有哪些TokenRanges,我就可以使用Cassandra.Client.describe_splits()获得大小均匀的分割。

一旦我有一堆可以从本地Cassandra实例中读取的大小均匀的分割,我就开始尽可能快地使用带有ConsistencyLevel.ONE的Cassandra.Client.get_range_slices()读取它们,这样它就不需要了做任何远程读取。我一次获取100行,顺序通过整个TokenRange(我尝试了各种批量大小,100似乎最适合这个应用程序)。

这一切在Cassandra 0.7.0上运行得很好,只需稍微调整内存大小和列族配置。通过这种方式,我可以每秒读取4000到5000条记录,并保持本地磁盘尽可能地工作。

以下是我在Cassandra 0.7.0下看到的分裂和速度的例子:

10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 20253030905057371310864605462970389448 : 21603066481002044331198075418409137847
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 21603066481002044331198075418409137847 : 22954928635254859789637508509439425340
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 22954928635254859789637508509439425340 : 24305566132297427526085826378091426496
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 24305566132297427526085826378091426496 : 25656389102612459596423578948163378922
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 25656389102612459596423578948163378922 : 27005014429213692076328107702662045855
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 27005014429213692076328107702662045855 : 28356863910078000000000000000000000000
10/12/20 20:13:18 INFO m4.TagGenerator: 42530 records read so far at a rate of 04250.87/s
10/12/20 20:13:28 INFO m4.TagGenerator: 90000 records read so far at a rate of 04498.43/s
10/12/20 20:13:38 INFO m4.TagGenerator: 135470 records read so far at a rate of 04514.01/s
10/12/20 20:13:48 INFO m4.TagGenerator: 183946 records read so far at a rate of 04597.16/s
10/12/20 20:13:58 INFO m4.TagGenerator: 232105 records read so far at a rate of 04640.62/s

当我升级到Cassandra 0.7.2时,我不得不重建配置,因为有一些新的选项等等,但我注意尝试从0.7.0配置中获得相同的所有相关调整设置工作。但是,我很难用新版本的Cassandra每秒读取50条记录。

以下是我在Cassandra 0.7.2下看到的分裂和速度的一个例子:

21:02:29.289 [main] INFO  c.p.m.a.batch.BulkCassandraReader - split - 50626015574749929715914856324464978537 : 51655803550438151478740341433770971587
21:02:29.290 [main] INFO  c.p.m.a.batch.BulkCassandraReader - split - 51655803550438151478740341433770971587 : 52653823936598659324985752464905867108
21:02:29.290 [main] INFO  c.p.m.a.batch.BulkCassandraReader - split - 52653823936598659324985752464905867108 : 53666243390660291830842663894184766908
21:02:29.290 [main] INFO  c.p.m.a.batch.BulkCassandraReader - split - 53666243390660291830842663894184766908 : 54679285704932468135374743350323835866
21:02:29.290 [main] INFO  c.p.m.a.batch.BulkCassandraReader - split - 54679285704932468135374743350323835866 : 55681782994511360383246832524957504246
21:02:29.291 [main] INFO  c.p.m.a.batch.BulkCassandraReader - split - 55681782994511360383246832524957504246 : 56713727820156410577229101238628035242
21:09:06.910 [Thread-0] INFO  c.p.m.assembly.batch.TagGenerator - 100 records read so far at a rate of 00000.25/s
21:13:00.953 [Thread-0] INFO  c.p.m.assembly.batch.TagGenerator - 10100 records read so far at a rate of 00015.96/s
21:14:53.893 [Thread-0] INFO  c.p.m.assembly.batch.TagGenerator - 20100 records read so far at a rate of 00026.96/s
21:16:37.451 [Thread-0] INFO  c.p.m.assembly.batch.TagGenerator - 30100 records read so far at a rate of 00035.44/s
21:18:35.895 [Thread-0] INFO  c.p.m.assembly.batch.TagGenerator - 40100 records read so far at a rate of 00041.44/s

正如您可能从日志中看到的那样,代码移动到了另一个包,但除此之外代码没有更改。它运行在相同的硬件上,所有内存设置都相同。

我可以看到Cassandra版本之间存在一些性能差异,但是因为这个(100倍性能下降)看起来像是惊天动地似乎我必须缺少一些基本的东西。甚至在调整0.7.0上的列族和内存设置之前,它就不会那么慢。

有谁知道可以解释这个问题?是否有一些我可能会错过的调整设置可能会导致这种情况? Cassandra函数有什么变化来支持刚刚没有记录的hadoop吗?通过发行说明阅读我找不到任何可以解释这一点的内容。任何有关解决这个问题的帮助,或者甚至只是解释它为什么停止工作的原因都将不胜感激。

2 个答案:

答案 0 :(得分:2)

我认为我应该关闭循环,因为我们已经解决了问题的根源,问题不是Cassandra问题,而是配置问题。

当我们升级到0.7.2时,一个改变的配置,我错过了,是令牌环。在我们的0.7.0配置中,我们将第一个令牌设置为2 ^ 127/12,并且在我们的0.7.2配置中,我们将第一个令牌设置为0.这导致一个节点获得分割0:0。 0:0似乎是一个神奇的范围,要求卡桑德拉一切。所以我们在集群中有一个节点通过网络提取所有数据。到该节点的网络流量最终导致我们成为问题的根源。

修复是纠正代码以检查0:0的情况并处理它,因此代码现在将处理以任何方式分区的Cassandra集群(第一个节点为0或其他)。

所以简而言之,不是Cassandra问题。我的配置问题。

答案 1 :(得分:1)

这里不响铃。我猜你是一个诚实的回归。

您可以尝试将磁盘访问模式切换为标准模式。您也可以尝试禁用JNA。 (这些应该分别绕过1713和1470,这是最有可能的罪魁祸首。但是,“最有可能”这里只是程度问题,我可能会给出20%的赔率。)

如果你可以使用contrib / stress将缓慢归结为可见的东西,那么我们可以从那里向后工作以找到原因。但是如果你只能用自己的设置重现,那么你必须将二分法(通过提交进行二进制搜索,部署构建并检查性能)来找出导致这种回归的原因。

为了将来参考,Cassandra用户列表是一个比StackOverflow更好的论坛“我认为我发现了一个bug”的讨论。那里有更多的专业知识。