Cassandra 轻量级事务性能惩罚

Cassandra Light weight transaction performance penalty

我有两个 cassandra table,一个记录 table 和一个计数器 table。 计数器table 为记录table 中的每种记录保留一个计数器。

当我向记录table插入一条新记录时,我会同时更新计数器table。但有可能新记录已经在记录 table 中。插入同一条记录两次是可以的,但是我会两次添加计数器,这是不正确的。

我现在有两个解决方案。

  1. 使用新的记录键从 cassandra 获取记录。如果它不为空,我不会插入记录并增加计数器。

  2. 使用轻量级事务让cassandra检查记录是否已经存在。

解决方案 2 将使插入 "atomic",但文档说它会降低性能。在解决方案 1 中,我发送了 2 个查询,这也会有性能损失。

目前我正在使用解决方案 1。我是 cassandra 轻量级事务的新手,所以我不知道原子性的成本。有谁知道哪种解决方案更好?

基本上你有几个选择:

  1. Insert "trusted" unique - 你 "somehow"" 知道你插入的任何项目在 table 中都不存在,所以你只需插入并增加计数器而不检查任何东西
  2. 插入轻量级交易 - 使用 IF NOT EXISTS(几乎可以保证一致性,除非增量计数器失败/超时 - 在这种罕见情况下,您可能 运行 不足或过度数数)。此选项允许并发客户端。
  3. Read/write 一致性级别为 ONE(如果您 运行 频繁插入,您可能 运行 陷入写入和读取之间的一致性问题;还要确保 NO并发客户端 做同样的事情)
  4. Read/write 具有一致性级别 QUORUM(读取将与上次写入一致,但是,您仍然必须确保没有并发客户端。

有一天,我 运行 对 m3.large 个实例 (https://aws.amazon.com/ec2/instance-types/) 的 3x Cassandra 集群进行了简单测试 在 单个 线程中,每个分区有 100 个分区和 100 个插入(因此总共有 10k 个插入)- 所以这不是 IO 饱和测试。

架构:

CREATE TABLE IF NOT EXISTS parent_children (
  parentId uuid,
  childId uuid, 
  PRIMARY KEY (parentId, childId)
);

CREATE TABLE IF NOT EXISTS child_counters (
  parentId uuid,
  count counter, 
  PRIMARY KEY (parentId)
);

结果:

Insertion Method    Latency per insert, ms
TRUSTED UNIQUE      1.6404
IF NOT EXISTS       4.2801
READ WRITE ONE      3.9382
READ WRITE QUORUM   3.7714

请注意,quorum 出人意料地快了一点,但可能在误差范围内 and/or 可能是由于集群拓扑的具体情况。