玩轉Redis-HyperLogLog統計微博日活月活

《玩轉Redis》系列文章主要講述Redis的基礎及中高級應用。本文是《玩轉Redis》系列第【9】篇,最新系列文章請前往公衆號「zxiaofan」查看,或百度搜索「玩轉Redis zxiaofan」便可。git

本文關鍵字:玩轉Redis、微博日活/月活、UV統計、HyperLogLog;程序員

大綱github

  • 日活數據統計面臨哪些挑戰
    • Bitmaps可用於統計日活嗎?
    • 日活數據統計的特色
  • HyperLogLog介紹
    • HyperLogLog必知
    • HyperLogLog和Sets的區別
  • HyperLogLog如何使用
    • HyperLogLog命令對比分析
    • HyperLogLog命令詳解
    • HyperLogLog命令注意事項
    • HyperLogLog命令示例
  • HyperLogLog的應用場景

名詞解釋算法

  • DAU(Daily Active User)日活躍用戶數量
    經常使用於反映網站、互聯網應用或網絡遊戲的運營狀況。DAU一般統計一日(統計日)以內,登陸或使用了某個產品的用戶數(去除重複登陸的用戶);
  • 月活躍用戶數量(Monthly Active User,MAU)
    月活躍用戶數量一般統計一個月(統計月)以內,登陸或使用了某個產品的用戶數(去除重複登陸的用戶);
  • Note:日活、月活反映用戶的活躍度,可是沒法反映用戶的粘性。

1. 日活數據統計面臨哪些挑戰

  2020年2月26日,微博發佈2019年第四季度及整年財報。數據顯示,截至2019年末,微博月活躍用戶達到5.16億,相比2018年年末淨增加約5400萬,其中移動端佔比94%。2019年微博整年營收提高至122.4億元,其中廣告營收達到106億元。緩存

1.1. Bitmaps可用於統計日活嗎?

  前文《玩轉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計算日活月活:微信

  • 計算日活:bitcount key獲取key爲1的數量;
  • 計算月活:可把30天的全部bitmap作or計算,再進行bitcount計算;
  • 計算留存率:昨日留存=昨天今天連續登陸的人數/昨天登陸的人數,即昨天的bitmap與今天的bitmap進行and計算,在除以昨天bitcount的數量。

  經過以上計算,咱們發現Bitmaps已經很節省空間了。統計一個網站的日活已不在話下,可是大型互聯網公司除了日活,還有UV、PV等等須要統計。面對上千甚至更多的需統計模塊,1個模塊1天須要12M,一年就須要12M * 365 / 1024 ≈ 4.3G ,1000個模塊一年就須要 12M * 365 / 1024 / 1024 ≈ 4.2T。So 革命還沒有成功,咱們還需再節省點!cookie

1.2. 日活數據統計的特色

  • 數據須要去重;
  • 數據容許有必定的誤差,101W和102W差距不大;
  • 佔用空間儘量小;

2. HyperLogLog介紹

2.1. HyperLogLog必知

  HyperLogLog(HLL)是一種用於基數計算的機率數據結構,通俗的說就是支持集合中不重複元素的統計。網絡

  常規基數計算須要準備一塊內存空間用於存儲已經計數的元素,避免某些元素被重複統計。Redis提供了一種用精度來換取內存空間的算法,標準偏差低於1%。僅須要12K 就能完成統計(再加上HLL自身所需的一點bytes),若是HyperLogLog中的元素較少,所需內存空間更小。HyperLogLogs的標準偏差是0.81%數據結構

  輸入元素數量或體積很是大時,HLL所需空間固定且很小。12kb內存可計算接近 2^64 個不一樣元素的基數

  HyperLogLog雖然技術實現是一種 不一樣的數據結構,但底層依舊是Redis strings,因此可使用GET命令獲取序列化後的數據,使用SET命令反序列化數據存儲到Redis。

2.2. HyperLogLog和Sets的區別

對比/數據類型 Sets HyperLogLog
是否實際存儲統計元素 存儲 不存儲元素,僅存儲存在的標記
增長元素 SADD PFADD
統計元素數量 SCARD PFCOUNT
刪除元素 SREM 不支持刪除元素

3. HyperLogLog如何使用

【HyperLogLog核心命令】:PFADD、PFCOUNT、PFMERGE;

3.1. HyperLogLog命令對比分析

命令 功能 參數
PFADD 添加元素到HLL數據結構 key element [element ...]
PFCOUNT 返回HLL的基數值 key [key ...]
PFMERGE 合併多個HLL結構數據到destkey destkey sourcekey [sourcekey ...]

  HLL操做命令中的PF含義:HyperLogLog 數據結構的發明人 Philippe Flajolet 的首字母縮寫。

3.2. HyperLogLog命令詳解

HyperLogLog命令詳解

3.3. HyperLogLog命令注意事項

  • PFADD僅存儲標記,不存儲元素自己;
  • PFCOUNT實際是一個write命令,執行PFCOUNT時可能會從新計算計數值並存儲;
  • key有多個時,PFCOUNT會動態合併計算,而且計算結果不會被緩存,因此生產環境執行PFCOUNT時儘可能避免帶多個key;
  • PFMERGE計算的是sourcekey的並集;
  • 若是destkey已存在,則PFMERGE執行後destkey最終的結果是dest+source的並集;

3.4. HyperLogLog命令示例

// 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
複製代碼

4. HyperLogLog應用場景

4.1. 網站日活月活

  日活:天天一個HLL,用戶登陸時則PFADD HLL20200719 userID;
  月活:合併當月的全部日活數據,PFMERGE HLL202007 HLL20200701 HLL20200702 HLL20200703 ...

4.2. 網頁UV

  UV(Unique Visitor)獨立訪客:1天內;cookie爲標識;相同的客戶端屢次訪問只計爲1個訪客。
  好比老闆想實時查看公司網站某些頁面從今天0點到如今被多少獨立訪客訪問。

4.3. 其餘場景場景

  • 搜索引擎關鍵詞搜索量;
  • 用戶在線人數統計;
  • 基於基數計數的數據分析場景。

【玩轉Redis系列文章 @zxiaofan】

《玩轉Redis-京東簽到領京豆如何實現》

《玩轉Redis-老闆帶你深刻理解分佈式鎖》

《玩轉Redis-如何高效訪問Redis中的海量數據》

《玩轉Redis-高級程序員必知的Key命令》

《玩轉Redis-研發也應該知道的Connection命令》

《玩轉Redis-Redis高級數據結構及核心命令-ZSet》

《玩轉Redis-Redis基礎數據結構及核心命令》

《玩轉Redis-Redis安裝、後臺啓動、卸載》


祝君好運!
Life is all about choices!
未來的你必定會感激如今拼命的本身!
CSDN】【GitHub】【OSCHINA】【掘金】【語雀】【微信公衆號
歡迎訂閱zxiaofan的微信公衆號,掃碼或直接搜索zxiaofan

相關文章
相關標籤/搜索