【问题标题】:set minimum counter value in cassandra counter table在 cassandra 计数器表中设置最小计数器值
【发布时间】:2016-05-14 22:39:30
【问题描述】:

在 cassandra 中有什么方法可以定义计数器列中计数器的最小值。假设当计数器值达到 0 时,即使我进行减量操作,它也不应该低于此值。

【问题讨论】:

    标签: cassandra cql


    【解决方案1】:

    没有。你的计数器被初始化为 0,你可以增加它,减少它,并查询它的值。它是 (-2^64 和 2^63 - 1) 之间的整数。达到最小值/最大值时,求和/减法将溢出。

    如果您尝试处理应用程序中的逻辑,如果您只有 1 个编写应用程序会很容易,但您可能有不止一个。如果您的应用程序位于可以使用锁的同一系统上,那将是可行的,我再次猜测情况并非如此,而且性能会下降。在分布式环境中,您需要能够获得分布式锁,性能会受到影响。

    如果你真的想用 Cassandra 实现这个功能,你可以用下面的策略来模拟它:

    1.表定义

    CREATE TABLE test.counter (
        my_key tinyint,
        my_random uuid,
        my_operation int,
        my_non_key tinyint,
        PRIMARY KEY ((my_key), my_operation, my_random)
    );
    

    此表将用于跟踪您正在运行的递增/递减操作。几点说明:

    • 分区键 my_key 将始终使用相同的值:0。它用于将所有操作(递增/递减)配置在同一分区键中。
    • my_random 值必须是生成的随机值,没有任何 碰撞的机会。 uuid 可以用于此。如果没有此列,执行两次相同的操作(例如递增 10)将只存储一次。每个操作都有自己的 uuid。
    • my_operation 跟踪您执行的增量/减量值。
    • my_non_key 是一个虚拟列,我们将使用它来查询写入时间戳,因为我们无法在主键列上查询它。我们将始终将 my_non_key 设置为 0。

    2。计数器初始化 您可以使用以下方法初始化计数器,例如归零:

    INSERT INTO test.counter  (my_key , my_random, my_operation, my_non_key ) VALUES
    ( 0, 419ec9cc-ef53-4767-942e-7f0bf9c63a9d, 0, 0);
    

    3.计数器增量 假设您添加了一些数字,例如 10。您可以通过插入相同的分区键 0、新的随机 uuid 和值 10 来实现:

    INSERT INTO test.counter  (my_key , my_random, my_operation, my_non_key) VALUES
    ( 0, d2c68d2a-9e40-486b-bb69-42a0c1d0c506, 10, 0);
    

    4.计数器递减 假设你现在减去 15:

    INSERT INTO test.counter  (my_key , my_random, my_operation, my_non_key ) VALUES
    ( 0, e7a5c52c-e1af-408f-960e-e98c48504dac, -15, 0);
    

    5.计数器增量 假设你现在加 1:

    INSERT INTO test.counter  (my_key , my_random, my_operation, my_non_key ) VALUES
    ( 0, 980554e6-5918-4c8d-b935-dde74e02109b, 1, 0);
    

    6.计数器查询 现在,假设您要查询您的计数器,您需要运行:

    SELECT my_operation, writetime(my_non_key), my_random FROM test.counter WHERE my_key = 0;
    

    这将返回:0; 10个; -15; 1 带有写入的时间戳。您的应用程序现在具有计算正确值的所有信息,因为它知道递增/递减操作发生的顺序。当计数器接近负值时,这当然是必要的。在这种情况下,您的应用程序应该能够计算出正确的值,即 1。

    6.清理 每隔一段时间,或者在查询计数器时,您可以将值组合在一起并在批处理语句中删除旧的以确保原子性,例如:

    BEGIN BATCH
    DELETE FROM test.counter WHERE my_key = 0 AND my_operation = -5 and my_random = e7a5c52c-e1af-408f-960e-e98c48504dac;
    DELETE FROM test.counter WHERE my_key = 0 AND my_operation = 0 and my_random = 419ec9cc-ef53-4767-942e-7f0bf9c63a9d;
    DELETE FROM test.counter WHERE my_key = 0 AND my_operation = 10 and my_random = d2c68d2a-9e40-486b-bb69-42a0c1d0c506;
    INSERT INTO test.counter  (my_key , my_random, my_operation, my_non_key ) VALUES (0, ca67df54-62c7-4d31-a79c-a0011439b486, 1, 0);
    APPLY BATCH;
    

    结语

    【讨论】:

    • 注意:cassandra 3.x 中的计数器表上不允许插入语句
    • 他这里没有使用计数器
    • 如此详细的答案不能不投票
    • 另一个答案不是真正需要的,但您仍然有可能。在计数器上完成读取时。如果值低于 0,则通过在 0 下添加 x 值并显示用户 0 来重置为 0。不是最好的,但这就是我想要的。
    猜你喜欢
    • 1970-01-01
    • 2021-11-18
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多