2013-03-13 108 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中加載該狀態(或者如果數據庫中沒有任何內容,則會創建一個新的狀態)。如果一個節點崩潰了,那麼操作沒有被確認,並且會被重新傳遞(你需要在節點前面有一個好的消息隊列來處理這個問題)。由於您對增量操作進行分片,因此可以確保只有一個節點才能觸摸計數器狀態。