【问题标题】:Cassandra Light weight transaction performance penaltyCassandra 轻量级事务性能损失
【发布时间】:2016-10-06 18:42:27
【问题描述】:

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

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

我现在有两个解决方案。

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

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

解决方案 2 将使插入“原子”,但文档说它会产生性能损失。在解决方案 1 中,我发送 2 个查询,这也会有性能损失。

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

【问题讨论】:

    标签: performance cassandra consistency nosql


    【解决方案1】:

    基本上你有几个选择:

    1. 插入“受信任”唯一 - 您“不知何故”提前知道您插入的任何项目都不存在于表中,因此您只需插入并递增计数器而不检查任何内容
    2. 使用轻量级事务插入 - 使用 IF NOT EXISTS(几乎可以保证一致性,除非增量计数器失败/超时 - 在这种极少数情况下,您可能会遇到计数不足或过度计数)。此选项允许并发客户端。
    3. 读/写一致性级别 ONE(如果您频繁运行插入,您可能会遇到写和读之间的一致性问题;还要确保没有并发客户端做同样的事情)
    4. 读/写一致性级别 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 出乎意料地快了一点,但这可能在误差范围内和/或可能是由于集群拓扑的具体情况。

    【讨论】:

    • 我想确认一下,在选项3和选项4中,您首先从parent_child中读取以测试项目是否存在,然后写入并在项目不存在时增加计数器,对吗?跨度>
    • 是的。但是,根据您的用例,有一些选项。例如,如果您想更新现有项目,则执行插入(实际上是 upsert),但跳过计数器增量
    猜你喜欢
    • 2021-10-17
    • 2014-09-19
    • 2018-05-08
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 2019-01-12
    • 1970-01-01
    相关资源
    最近更新 更多