2013-03-13 72 views
4

我需要在卡桑德拉数一堆“东西”。 我需要每隔几秒左右增加〜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 +++)。

目前我正在考虑使用东京内阁作为外部键/价值商店, 但这种解决方案,如果工作,将不会像Cassandra那样具有可扩展性。

回答

3

当不同值的数目很大时,使用Cassandra进行不同计数并不理想。任何时候你需要在写作之前进行阅读,你应该问问自己,卡桑德拉是否是正确的选择。

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

人们通常会这样做的方式是在内存中使用HLL或Bloom过滤器,然后定期将它们刷新到Cassandra。即没有在卡桑德拉做实际的操作,只是用它来坚持。这是一个复杂的系统,但可以轻松计算不同的值,特别是如果您拥有大量计数器。

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