《玩轉Redis》系列文章主要講述Redis的基礎及中高級應用。本文是《玩轉Redis》系列第【9】篇,最新系列文章請前往公衆號「zxiaofan」查看,或百度搜索「玩轉Redis zxiaofan」便可。git
本文關鍵字:玩轉Redis、微博日活/月活、UV統計、HyperLogLog;程序員
大綱github
名詞解釋算法
2020年2月26日,微博發佈2019年第四季度及整年財報。數據顯示,截至2019年末,微博月活躍用戶達到5.16億,相比2018年年末淨增加約5400萬,其中移動端佔比94%。2019年微博整年營收提高至122.4億元,其中廣告營收達到106億元。緩存
前文《玩轉Redis-京東簽到領京豆如何實現》提到了 Bitmaps 在大數據下的應用,那麼Bitmaps能夠用於統計日活數據嗎?咱們來作個計算分析(以一億用戶爲例):bash
統計方式 | 佔用計算 | 1億用戶佔用空間(M) |
---|---|---|
MySQL 32bit的int數據類型 | 1個int所需存儲空間爲4字節,可存儲32 bit位 | 10^8 / (1024 * 1024 * 8 / 32) ≈ 381 M |
Redis Bitmaps | Bitmaps單個支持512M,不像int單個僅存儲32位 | 10^8 / (1024 * 1024 * 8) ≈ 12M |
使用Bitmaps計算日活月活:微信
經過以上計算,咱們發現Bitmaps已經很節省空間了。統計一個網站的日活已不在話下,可是大型互聯網公司除了日活,還有UV、PV等等須要統計。面對上千甚至更多的需統計模塊,1個模塊1天須要12M,一年就須要12M * 365 / 1024 ≈ 4.3G ,1000個模塊一年就須要 12M * 365 / 1024 / 1024 ≈ 4.2T。So 革命還沒有成功,咱們還需再節省點!cookie
HyperLogLog(HLL)是一種用於基數計算的機率數據結構,通俗的說就是支持集合中不重複元素的統計。網絡
常規基數計算須要準備一塊內存空間用於存儲已經計數的元素,避免某些元素被重複統計。Redis提供了一種用精度來換取內存空間的算法,標準偏差低於1%。僅須要12K 就能完成統計(再加上HLL自身所需的一點bytes),若是HyperLogLog中的元素較少,所需內存空間更小。HyperLogLogs的標準偏差是0.81%。數據結構
輸入元素數量或體積很是大時,HLL所需空間固定且很小。12kb內存可計算接近 2^64 個不一樣元素的基數。
HyperLogLog雖然技術實現是一種 不一樣的數據結構,但底層依舊是Redis strings,因此可使用GET命令獲取序列化後的數據,使用SET命令反序列化數據存儲到Redis。
對比/數據類型 | Sets | HyperLogLog |
---|---|---|
是否實際存儲統計元素 | 存儲 | 不存儲元素,僅存儲存在的標記 |
增長元素 | SADD | PFADD |
統計元素數量 | SCARD | PFCOUNT |
刪除元素 | SREM | 不支持刪除元素 |
【HyperLogLog核心命令】:PFADD、PFCOUNT、PFMERGE;
命令 | 功能 | 參數 |
---|---|---|
PFADD | 添加元素到HLL數據結構 | key element [element ...] |
PFCOUNT | 返回HLL的基數值 | key [key ...] |
PFMERGE | 合併多個HLL結構數據到destkey | destkey sourcekey [sourcekey ...] |
HLL操做命令中的PF含義:HyperLogLog 數據結構的發明人 Philippe Flajolet 的首字母縮寫。
// pfadd、pfcount 示例 @zxiaofan
127.0.0.1:6379> pfadd hll 1
(integer) 1
127.0.0.1:6379> pfadd hll 1
(integer) 0
127.0.0.1:6379> pfadd hll 2 3 4
(integer) 1
127.0.0.1:6379> pfcount hll
(integer) 4
127.0.0.1:6379> pfcount hll:notexist
(integer) 0
127.0.0.1:6379> pfadd hll2 a b
(integer) 1
127.0.0.1:6379> pfcount hll2
(integer) 2
127.0.0.1:6379> pfcount hll hll2
(integer) 6
127.0.0.1:6379> get hll
"HYLL\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00A\xee\x84[v\x80Mt\x80Q,\x8cC\xf3"
127.0.0.1:6379> set hll:error error666
OK
127.0.0.1:6379> pfcount hll:error
(error) WRONGTYPE Key is not a valid HyperLogLog string value.
複製代碼
// pfmerge 示例 @zxiaofan
127.0.0.1:6379> pfadd hllm1 1 2 3 4 5
(integer) 1
127.0.0.1:6379> pfadd hllm2 5 6 7 8
(integer) 1
127.0.0.1:6379> pfmerge hllm3 hllm1 hllm2
OK
127.0.0.1:6379> pfcount hllm3
(integer) 8
127.0.0.1:6379> pfadd hllm4 7 8 9 10 11 12 14 14
(integer) 1
127.0.0.1:6379> pfmerge hllm4 hllm1 hllm2
OK
127.0.0.1:6379> pfcount hllm4
(integer) 13
複製代碼
日活:天天一個HLL,用戶登陸時則PFADD HLL20200719 userID;
月活:合併當月的全部日活數據,PFMERGE HLL202007 HLL20200701 HLL20200702 HLL20200703 ...
UV(Unique Visitor)獨立訪客:1天內;cookie爲標識;相同的客戶端屢次訪問只計爲1個訪客。
好比老闆想實時查看公司網站某些頁面從今天0點到如今被多少獨立訪客訪問。
【玩轉Redis系列文章 @zxiaofan】
《玩轉Redis-研發也應該知道的Connection命令》
《玩轉Redis-Redis高級數據結構及核心命令-ZSet》
祝君好運!
Life is all about choices!
未來的你必定會感激如今拼命的本身!
【CSDN】【GitHub】【OSCHINA】【掘金】【語雀】【微信公衆號】