Redis 統計uv

平常接需求的時候, PM提出來一個須要統計頁面UV/PV的需求你怎麼作?html

場景

下面有三個選擇:mysql

  1. 甩給公司的大數據部門, 讓他們搞去
  2. 開始記錄ip ,而後去重統計, b數/mysql/redis/hashMap等等
  3. bitmap
  4. 使用 HyperLogLog 算法

首先, 選1的時候看公司架構怎麼說, 若是人家給你排期到半個月後了你這需求還作不作了?redis

其次, 選2是咱們的大多數狀況, 並且是最直白的一種統計方式.
這種方式的好處就是統計準確, 且能保留住數據, 在特定的業務裏面還能複用(好比作個ip黑名單, 反做弊啥的).
固然缺點也很明顯, 若是你的服務請求量特別大, 那麼你存儲數據的體積增加特別快. 算法

好比放到redis的集合裏面(曾經我就這麼幹過), 把全部請求的ip存到redis中, 最後統計集合中元素的個數, 後來運維開始在羣裏嚷嚷:我們緩存服務的內存要不夠用啦!
運維把大key一列, 嗯? xx, 你這緩存能優化一下不? 這幾百mb的冷數據扔緩存裏面太浪費資源了balabalasql

總之就是你得優化一下了, 那麼怎麼優化呢? 緩存

bitmap也是一種不錯的方式, 把十進制映射到bit字節上, 好比 10000000 個基數, 那麼轉換後就變成了 100000000/8/1024/1024 ≈ 12M, 這也是個不錯的選擇, 不過key不少的狀況下佔用空間也很多架構

通過我一番谷歌+翻文檔, 發現了這麼個神奇的東西: HyperLogLog, 基於機率這種玄學的算法運維

在redis中的使用

Redis 在 2.8.9 版本添加了 HyperLogLog 結構, 它的優點就是每一個key僅需12kb的內存, 就能存儲 2^64 個不一樣元素的基數, 存儲空間小且固定, 缺點就是元數據沒法直接提取了post

這種是基於機率的算法, 既然是機率就包含着不肯定性, 存在統計偏差, 不過大部分場景是能hold住的, 若是須要絕對精確的狀況, 不要用這個大數據

使用的命令以下:

127.0.0.1:6379> PFADD test_uv id1 id2 id3 id4 id1
(integer) 1
127.0.0.1:6379> PFCOUNT test_uv
(integer) 4
127.0.0.1:6379> PFADD test_uv2 id1 id2 id5
(integer) 1
127.0.0.1:6379> PFMERGE test_uv3 test_uv test_uv2
OK
127.0.0.1:6379> PFCOUNT test_uv3
(integer) 5

PFADD 添加基數

PFCOUNT 統計個數

PFMERGE 兩個key合併

就是這麼簡單, 粗暴

算法原理

這個我也是看的別人的, 因此就把這兩篇文章列出來本身複習一下:

相關文章
相關標籤/搜索