離線資料處理與實時資料處理有很大的不同,其中乙個例子就是去重。在聚資料中,訪問uv和購買uv都需要實時的去重。離線處理的時候,我們可以通過count(groupby)或者count(distinct)等方式比較容易的計算出uv,而且不用太擔心效能,大不了就是多一點map或者執行時間久一點。那麼在實時計算的時候,我們有什麼好的辦法來做這個事情呢?
在聚資料中有兩種場景:
1,資料的準確性要求高,最好就是完全準確的,例如購買uv。同時交易資料量比較小,聚划算每天的交易筆數僅在百萬級別。對於這樣的情況,我們採用了基於hbase的過濾。具體做法如下:
建立hbase去重表,對columnfamily設定過期時間,如:hcolumndescriptor.settimetolive(3*24*60*60);這樣3天後的資料將自動刪除,以免表過大。然後利用hbase的increment計數,判斷計數值是否等於1即可。非常簡單粗暴。
2,資料的準確性要求不是很嚴格,允許有少許的誤差,例如訪問uv。往往資料量也比較大,聚划算每天的訪問uv在千萬級別。這種情況我們想到了bloomfilter,也就是本文的重點。
bloomfilter原理:
簡單的說就是:通過將乙個key的hash值分布到乙個大的bit陣列上面,判斷乙個key是否存在時只需判斷該的hash對應的bit位是否都是1,如果全是1則表示存在,否則不存在。
優點:效能很高主要在hash演算法上面,空間占用小,能夠極大的縮小儲存空間。
缺點:存在誤判。既對應的bit位剛好被其他的key置為1了。
好在誤判率是可控的,我們假設kn對於公式對應的具體原理,個人覺得不必去深究,只需要記住下面兩句話,即可將bloomfilter應用自如:
1,如果他告訴你不存在,則一定不存在;
2,如果他告訴你存在,則可能不存在。
因此bloomfilter最理想的應用場景是在一些複雜的查詢時,在db上做一層bloomfilter判斷,如果bloomfilter判斷不存在,則沒必要到db去查了。頂多就是出現誤判時,多到db查詢一下,而這個概率是很低的。
上面說到的bloomfilter還緊緊是單機記憶體的,在**這個環境下,顯然是不適用的。那麼我們如何把他變成分布式的呢?看了標題我想你已經知道了,對了,那就是redis。
bloomfilter需要的bit陣列與redis的bit操作真是完美契合啊。利用redis的高效能以及通過pipeline將多條bit操作命令批量提交,實現了多機bloomfilter的bit資料共享。唯一需要注意的是redis的bitmap只支援2^32大小,對應到記憶體也就是512mb,陣列的下標最大只能是2^32-1。不過這個限制我們可以通過構建多個redis的bitmap通過hash取模的方式分散一下即可。同時利用上面的公式計算一下:萬分之一的誤判率,512mb可以放下2億左右的資料,而目前全網的uv也就8千萬,所以,***。
基於keepalived的redis通訊鏈結數測試
使用keepalived做負載均衡後發現了乙個問題 作為realserver的redis伺服器上有許多開啟的監聽連線長久時間的不關閉 做個測試,檢查下問題的所在 初步判斷是和客戶端使用redis鏈結的方式有關 其次是由於網路波動造成的連線中斷,由於keepalived的原因無法關閉realserve...
redis過期監聽效能 基於Redis的延遲處理
延遲處理是乙個非常常用的乙個功能 例如,下單成功後,在30分鐘內沒有支付,自動取消訂單 延遲佇列便是延遲處理中最常見的實現方式 先一起看下jdk中延遲佇列是如何實現的.在jdk中,提供了一套延遲佇列的實現,是juc包中delayqueue類.在使用時只需要讓處理的元素物件實現delayed介面,就可...
基於Ubuntu的Redis的安裝
方法二 手動安裝 step2 解壓 step3 移動 step4 生成 step5 測試 step6 安裝 開啟ubuntu終端,依次輸入下面兩行 即可 sudo apt get update sudo apt get install redis server 判斷是否安裝成功 使用tar解壓安裝包...