2013-08-28 59 views
0

爲了獲得某種度量的某種分佈,我們在Cassandra中使用計數器,即與mysql中的group類似。但是,如果我想獨特地分配一項措施 - 我該怎麼做?Cassandra中的不同計數器

說我需要每天訪問網頁的用戶分佈 - 櫃檯非常方便。關鍵將是一天,價值將成爲一個計數器。但對於相同的網頁 - 如果我需要我需要獨特的用戶分佈,我怎樣才能實現使用Cassandra?

我可以以各種方式實現它 - 讀寫前,離線處理等。 我也聽說過位圖/超級日誌日誌計數器等什麼是最簡單和簡單的解決方案,我可以用/在卡桑德拉得到用戶獨特的日常分佈。我每天有數百萬的事件。

例子:

發言權25/08/2013 - 這是我的網頁上點擊 - 用戶1,用戶2,用戶1,用戶3

在26/08/2013 - 用戶1,用戶2

在27/08/2013 - 用戶2,用戶3,USER4

在28/08/2013 - 用戶1,用戶2,用戶1,用戶3

我的輸出應該

25/08/2013 - 3獨特的用戶

26/08/2013 - 2獨特的用戶

27/08/2013 - 3獨特的用戶

28/08/2013 - 3個獨特用戶

即天vs獨特用戶數。

感謝

回答

0

很多將取決於性能要求,一致性保證,系統等(幾乎是一個標準)的數字。這就是說,如果願意讓它具有概率性,我確實有一個建議,並且你不需要立即不斷地更新它。 HyperLogLog,正如你所提到的,是一個不錯的選擇。

每個服務器都可以在內存中保留一個,當數據插入時它會更新並定期(即每分鐘一次)推送到cassandra ...或其他存儲區。由於HyperLogLog的性質,當您想查詢它時,您可以對服務器hyperlog進行列切片並將它們組合起來。

ColumnFamilyHyperLogLogs: { 
    someMetricsCardinalityRow20130828: { 
    Server1: HyperLogLogBlob, 
    Server2: HyperLogLogBlob, 
    Server3: HyperLogLogBlob 
    } 
} 

我會建議clearsprings庫這就是我們偉大的工作:

https://github.com/clearspring/stream-lib/blob/master/src/main/java/com/clearspring/analytics/stream/cardinality/HyperLogLog.java

它轉換成字節數組,你可以使用序列化和反序列化,並具有能結合方法的功能他們。

另外,一些需要更多空間的東西是,你可以爲每件事物設置一排,就像你說的唯一用戶。

ColumnFamilyName { 
    uniqueUserOn20130828: { 
    "user1" : null, 
    "user2" : null, 
    ... 
    } 
} 

然後你可以在行上調用一個計數器,它會給你唯一用戶的確切數量。這是非常直截了當的,更容易實現,但它會佔用更多的空間,但還有額外的好處,您可以查看那一天用戶實際上在哪裏。這大概可以做很容易與CQL3,並設置具體

+0

第二種方法爲我們提供了一天中唯一的用戶。但我希望通過功能實現組合,這意味着我需要多個查詢才能獲得每日分發。我可以在單個查詢中實現相同嗎? – mac

+0

如果使用thrift,您可以使用multiget_count將它們全部置於一個查詢中。不確定CQL中的等價物。如果希望以更專業的方式來完成這項工作,Hadoop也可以用於cassandra。 –

0

沒有卡桑德拉但如果這個數據是仿照像下面

date  user_id 

25Aug2013 1 
25Aug2013 2 
25Aug2013 1 
25Aug2013 3 

26Aug2013 1 
26Aug2013 2 

27Aug2013 2 
27Aug2013 3 
27Aug2013 4 

28Aug2013 1 
28Aug2013 2 
28Aug2013 1 
28Aug2013 3 

您可以通過執行

按天或按月或任何其他日期格式獲得的唯一身份
select count(DISTINCT user_id), date from <table_name> where date_trunc(date, 'month') =8 order by user_id, format(date, 'DDMMYYY) DESC/ASC 

日期格式是可選的。您應該能夠在沒有該表的情況下查詢整個表,然後添加適當的過濾器。

+0

我想,你的意思是分組?如果是的話,那麼在Cass中,group by不存在:( – mac

+0

不是,我的意思是排序,因爲distinct會選擇多個不同的條目中的第一個,這取決於ORDER BY –

0

更新爲

CREATE TABLE user_day(
    day TEXT, 
    user_id TEXT, 
    user_count COUNTER, 
    PRIMARY KEY (day,user_id)); 

表定義如下:

UPDATE user_day SET user_count = user_count + 1 WHERE day = '20130829' AND user_id = 'USER-1'; 
UPDATE user_day SET user_count = user_count + 1 WHERE day = '20130829' AND user_id = 'USER-1'; 
UPDATE user_day SET user_count = user_count + 1 WHERE day = '20130829' AND user_id = 'USER-2'; 
UPDATE user_day SET user_count = user_count + 1 WHERE day = '20130829' AND user_id = 'USER-2'; 
UPDATE user_day SET user_count = user_count + 1 WHERE day = '20130829' AND user_id = 'USER-1'; 
UPDATE user_day SET user_count = user_count + 1 WHERE day = '20130829' AND user_id = 'USER-3'; 

會再給予兩種:

SELECT * FROM user_day; 

day  | user_id | user_count 
----------+---------+------------ 
20130829 | USER-1 |   4 
20130829 | USER-2 |   2 
20130829 | USER-3 |   1 

和:

SELECT COUNT(*) FROM user_day WHERE day = '20130829'; 


count 
------- 
    3 

WRT來評論,你要找的是一個卡桑德拉不支持的GROUP BY函數。您可以查看付費選項,如AcunuDatastax Enterprise offerings。如果你正在尋找一個免費的選項,那麼像amplabs spark and shark這樣的特殊查詢是非常好的,但我沒有親自使用它們與卡桑德拉我知道它已經完成。

+0

它爲您提供了唯一的用戶我需要再次查詢我需要所有來自25/08 - 28/08的唯一用戶在一天內以上述格式 – mac

+0

Cassandra!=關係數據庫C *數據建模通常有利於根據你想要查詢的數據存儲你的數據,這往往會導致非規範化(根據關係思維)結構。Cassandra非常擅長支持寫入可伸縮性和高容量存儲,因此不會被阻止以多種方式寫入數據,如需要閱讀 – Gavin

+0

我不會爲多次寫入日期而煩惱 - 我很擔心在一個查詢中獲取我所需的數據 - 而不是多個查詢。這種情況下,在一個查詢中 - 我如何獲得所有日子的唯一計數? – mac