今天,我和大家分享下redis在運維數據分析中的去重統計方式。為了避免混淆,本文中對于redis的數據結構做如下約定:
SET:saddkey member
ZSET:zaddkeyscoremember
HYPERLOGLOG:pfaddkey element
STRING:setbitkey offset value
名詞約定:
維度:比如版本、操作系統類型、操作系統版本、運營商、設備型號、網絡類型等
復合維度:由兩個或多個維度交錯產生的維度,比如某個版本下的某個設備型號。
去重統計在數據化運維的指標計算環節,并不是一個陌生的字眼,甚至可以說,在大部分的數據指標的中間計算過程中,最終會分為以下幾種數據集:
最大,最小,穩定性,疊加,去重統計。
這5種指標前面4種在實時處理框架或者大部分nosql中使用相對較小的開銷即可完成計算,基礎指標計算的大部分計算瓶頸還是落在io上面,而導致io瓶頸的問題源自于數據維度的劃分與聚合,特別是對于去重統計類型的數據,如果有一種需要實時顯示的去重指標,維度的切分對于io上的開銷簡直是一種災難。
例如,假定我們需要獲取手機終端中某個應用版本中的某個設備型號或者某個系統的活躍設備數。那么,目前市場中的設備型號有幾百種,各種系統版本x系統類型也有很多,對指標的去重統計來說每多一個維度,需要的內存開銷就要多上一倍,2個維度交叉產生的復合維度可能多達上百個,3個維度的交叉產生的復合維度可能數以千計。
因此,對于實時顯示的去重統計類型指標,最好的處理方式是在設計時盡量規避這種指標。如果實在無法規避,我們需要做的犧牲一部分插入時的性能或者空間上的性能換來該部分指標在讀取時不是o(n)的。
下面簡單介紹幾種在開發中基于redis研究出來的幾種數據去重方式:
1.于set的去重統計
這種結構的數據應該是最好理解的統計方式,也是常規的統計方式之一,直接把要去重的部分作為member插入一個set中,需要統計的時候直接使用scard統計該數據集的基數,對于時間等維度信息,可以放在key中,然后拿取的時候通過拼接維度字段的形式拿取。
圖1 set的去重統計
優點:使用簡單,統計精確。
缺點:無法達成實時統計的功能,要一分鐘統計一次的話需要使用expire命令設置一個很短的回收時間,單一維度時占用空間過大,信息聚合成本過大,有幾個維度就需要幾倍的內存空間,3個以上復合維度時基本不需要考慮此方案。
適用場景:需要統計的去重內容的基數非常小的情況下可以考慮,在優云mobile中,對于用戶基數較小的影響設備數的計算采用了此種方式。
2.基于zset的去重統計
傳統的基于跳表/B樹的統計方式,key為維度信息,score為時間,member為設備id等原子信息,通過zcount可以拿取所有的成員數量。
優點:插入和統計都是o(log(N))的,可以精確統計從現在開始到某個時間點的用戶,可以保留原子數據。
圖2 zset的去重統計
缺點:只能自定義時間域上的左區間,對于右區間只能定義為現在時間,否則會出現統計值比實際值偏小的情況(因為同一個設備如果出現兩次,則會移除舊的那條),單一維度時占用空間過大,有幾個維度就需要幾倍的內存空間,3個以上復合維度時基本不需要考慮此方案。
適用場景:對于查看從現在開始1分鐘 5分鐘 10分鐘等各種時間跨度的用戶基數時可以考慮,在優云mobile中,采用了這種方案來統計活躍設備數,早期開發時我們將各種時間維度和各種復合維度全部放在了redis中,結果發現內存開銷過大,現在的版本我們只存放了最近2分鐘的一些簡單維度的數據。
3.基于bitset的去重統計
將終端用戶id映射為一個bitset上的一個bit,利用現代處理器的特性進行快速計算。
優點:統計結果精確,對于不同維度可以使用and或者or進行聚合,數據具有原子性,通過較少的操作即可做到跨維度的計算。
圖3 bitset的去重統計
缺點:不適用于分鐘級別的統計,并且用戶id的映射較為麻煩。如果使用hash的方式進行映射,將會不可避免的產生hash碰撞,如果使用用戶id進行映射,那么必然需要維護一份用戶id映射表,這份映射表放在內存中會占用大量空間,放在磁盤中則會導致整個系統的處理速率降低。
備注:java中的bitset在一個byte字節上是由低位到高位進行存儲,redis中則是由高位到低位進行存儲。
適用場景:適用于需要儲存原子數據并進行較大時間跨度或者自由拼接時間跨度聚合的場景。
4.基于hyperloglog的去重統計
hyperloglog是一種基于概率的統計方式,在redis的2.8.9版本后出現的新數據結構
詳細的內容可以查看這幾篇文章:
http://blog.codinglabs.org/tag.html#基數估計
優點:每個hyperloglog只需要12K的空間,并且誤算率只有0.81%,不同的紀錄之間可以進行聚合,也就是可以通過聚合統計出任意時間范圍的去重結果,統計單個hyperloglog時時間復雜度為o(1)。
缺點:對于統計結果要求較為精確的場合并不是非常適用
適用場景:在對誤算率要求不高的情況下,同bitset。
5.基于布隆過濾器的去重統計
布隆過濾器是一種改良的bit映射方案,通過使用多種不同的hash種子,可以做到在較低誤判率以及較高的空間利用率的情況下進行統計,redis中并沒有布隆過濾器這個數據結構,不過可以通過lua腳本的方式實現一個布隆過濾器,詳細源碼可見
https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter1
圖4 布隆過濾器的去重統計
優點:對于200萬用戶不超過萬分之一誤算率的統計,只需要8M左右redis內存即可完成統計,萬分之一的誤算率是在插入的不同設備數達200萬次時才擁有的誤算率,在這之前的誤算率是從0開始線性增長的,在大多數情況下這個誤算率應該是可以容忍的。
缺點:布隆過濾器的統計結果無法聚合
適用場景:對于一些需要實時顯示的內容并且維度較少的內容,可以采用此數據結構,在優云mobile中,總覽頁面的活躍設備數采用了此方案來實時顯示今日活躍設備數。
核心關注:拓步ERP系統平臺是覆蓋了眾多的業務領域、行業應用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業務管理理念,功能涉及供應鏈、成本、制造、CRM、HR等眾多業務領域的管理,全面涵蓋了企業關注ERP管理系統的核心領域,是眾多中小企業信息化建設首選的ERP管理軟件信賴品牌。
轉載請注明出處:拓步ERP資訊網http://www.guhuozai8.cn/
本文標題:漫談redis在運維數據分析中的去重統計方式
本文網址:http://www.guhuozai8.cn/html/solutions/14019319372.html