1

如果我在一个集群中有一个包含 100'000 个已删除行的单个分区,然后在同一分区中有一个没有删除行的第二个集群,那么执行操作的性能SELECT * FROM example_table WHERE partition=that_partition AND cluster=the_second_cluster会受到 the_first_cluster 中存在的墓碑的影响吗?

我期望如果使用 where 子句检索行集是恒定的,那么 Cassandra 将跳过所有墓碑到第二个集群,但我不明白 where 子句如何找到正确的行,所以我不'不知道是否是这种情况,我没有设法在网上找到任何可以启发我的东西。

// Example table
CREATE TABLE example_table (
  partition TEXT,
  cluster TEXT,
  value BLOB,

  PRIMARY KEY (partition, cluster);

// Example layout of rows in a table
partition      |cluster            |value
that_partition |the_first_cluster  |some_value1 // Deleted, a tombstone
that_partition |the_first_cluster  |some_value2 // Deleted, a tombstone
... 99'997 more similar tombstone rows
that_partition |the_first_cluster  |some_value  // Deleted, a tombstone
that_partition |the_second_cluster |some_valueA // Not a tombstone
that_partition |the_second_cluster |some_valueB // Not a tombstone
... no tombstones in the_second_cluster
4

1 回答 1

4

如果结果中包含许多逻辑删除,则分区上的许多逻辑删除会显着影响性能。一篇好的文章https://www.datastax.com/dev/blog/cassandra-anti-patterns-queues-and-queue-like-datasets谈到了它。根据查询,它可能最终读取所有 100,000 个墓碑,如果在不同的 sstable 上满足查询,还可能读取原始数据。这会在堆上产生大量垃圾,并将影响 JVM GC 以及单个查询的大量 CPU 和 IO。

但是,如果墓碑是点删除而不是范围墓碑,并且您的查询直接转到未删除的键的分区+集群,那么您就可以了。不过这是一条很好的路线,我建议不要尝试它(如果有人尝试从应用程序中读取它作为操作/测试任务怎么办?它可能会导致长时间的 GC 并对集群产生负面影响)。保留在分区索引中的范围墓碑被反序列化,作为读取要跳转到的位置以获得行的列索引大小的一部分,因此即使不直接读取它们,它仍然会根据你的墓碑插入方式显着影响分配率。

设置了一个墓碑警告/失败阈值,cassandra.yaml因此它会让您知道您的查询是否正在命中它们,但是在您遇到故障点并且查询因刚刚在日志中报告而死亡之前很难判断。

我建议您对分区进行时间限制,以限制每个分区中的墓碑数量。

于 2018-04-24T14:29:20.163 回答