【问题标题】:Cassandra distinct countingCassandra 不同计数
【发布时间】:2015-02-17 09:58:48
【问题描述】:

我需要计算 Cassandra 中的一堆“东西”。 我需要每隔几秒左右增加约 100-200 个计数器。

但是我需要计算不同的“事物”。

为了不计算两次,我在 CF 中设置了一个键,程序在增加计数器之前读取该键,例如类似:

result = get cf[key];
if (result == NULL){
    set          cf[key][x] = 1;
    incr counter_cf[key][x];
}

但是,此读取操作会大大降低集群速度。 我尝试使用几列来减少读取,例如类似:

result = get cf[key];

if (result[key1]){
    set          cf[key1][x] = 1;
    incr counter_cf[key1][x];
}

if (result[key2]){
    set          cf[key2][x] = 1;
    incr counter_cf[key2][x];
}

//etc....

然后我将读取从 200+ 减少到大约 5-6,但它仍然减慢了集群的速度。

我不需要精确计数,但我不能使用位掩码,也不能使用布隆过滤器, 因为会有 1M+++ 计数器,有些可能超过 4 000 000 000。

我知道 Hyper_Log_Log 计数,但我也看不到将它与这么多计数器 (1M+++) 一起使用的简单方法。

目前我正在考虑使用 Tokyo Cabinet 作为外部键/值存储, 但是这个解决方案,如果可行的话,将不会像 Cassandra 那样具有可扩展性。

【问题讨论】:

    标签: cassandra distinct-values


    【解决方案1】:

    当不同值的数量很大时,使用 Cassandra 进行不同计数并不理想。任何时候你需要先读再写,你应该问问自己 Cassandra 是否是正确的选择。

    如果不同项目的数量较少,您可以将它们存储为列键并进行计数。计数不是免费的,Cassandra 仍然必须组装行来计算列数,但如果不同值的数量在数千个数量级,它可能会没问题。我假设你已经考虑过这个选项并且它对你来说不可行,我只是想我会提到它。

    人们通常这样做的方式是将 HLL 或 Bloom 过滤器放在内存中,然后定期将它们刷新到 Cassandra。 IE。不在 Cassandra 中进行实际操作,只是将其用于持久性。这是一个复杂的系统,但有一种简单的方法可以计算不同的值,尤其是在您有大量计数器的情况下。

    即使你切换到其他东西,例如你可以对值进行位操作的东西,你仍然需要防止竞争条件。我建议你只是咬紧牙关,在记忆中做所有的计数。通过键对处理节点上的增量操作进行分片,并将整个计数器状态(增量和不同)保存在这些节点的内存中。定期将状态刷新到 Cassandra,并在执行时确认增量操作。当一个节点对它在内存中没有的键进行增量操作时,它会从 Cassandra 加载该状态(如果数据库中没有任何内容,则创建一个新状态)。如果一个节点崩溃,操作还没有被确认并将被重新传递(你需要在节点前面有一个好的消息队列来处理这个问题)。由于您对增量操作进行了分片,因此您可以确保计数器状态只被一个节点触及。

    【讨论】:

      猜你喜欢
      • 2017-08-28
      • 1970-01-01
      • 2014-05-07
      • 2020-01-28
      • 1970-01-01
      • 2016-10-07
      • 1970-01-01
      • 2017-08-06
      • 2019-05-19
      相关资源
      最近更新 更多