拼多多面試真題:如何用 Redis 統計獨立用戶訪問量!

閱讀本文大概須要 2.8 分鐘。

做者:沙茶敏碎碎念前端

衆所周至,拼多多的待遇也是高的可怕,在挖人方面也是竭盡全力,對於一些工做 3 年的開發,稍微優秀一點的,都給到 30K 的 Offer。程序員

固然,拼多多加班也是出名的,一週上 6 天班是常態,天天工做時間基本都是超過 12 個小時,也是至關辛苦的。面試

廢話很少說,今天咱們來聊一聊拼多多的一道後臺面試真題,是一道簡單的架構類的題目:算法

拼多多有數億的用戶,那麼對於某個網頁,怎麼使用 Redis 來統計一個網站的用戶訪問數呢?微信

使用 Hash數據結構

哈希是 Redis 的一種基礎數據結構,Redis 底層維護的是一個開散列,會把不一樣的 key 映射到哈希表上,若是是遇到關鍵字衝突,那麼就會拉出一個鏈表出來。架構

當一個用戶訪問的時候,若是用戶登錄過,那麼咱們就使用用戶的 id,若是用戶沒有登錄過,那麼咱們也可以前端頁面隨機生成一個 key 用來標識用戶。性能

當用戶訪問的時候,咱們可使用 HSET 命令,key 能夠選擇 URI 與對應的日期進行拼湊,field 可使用用戶的 id 或者隨機標識,value 能夠簡單設置爲 1。學習

當咱們要統計某一個網站某一天的訪問量的時候,就能夠直接使用 HLEN 來獲得最終的結果了。網站

優勢:簡單,容易實現,查詢也是很是方便,數據準確性很是高。

缺點:佔用內存過大,隨着 key 的增多,性能也會降低。小網站還行,拼多多這種數億 PV 的網站確定受不了

使用 Bitset

咱們知道,對於一個 32 位的 int,若是咱們只用來記錄 id,那麼只可以記錄一個用戶,但若是咱們轉成 2 進制,每位用來表示一個用戶,那麼咱們就可以一口氣表示 32 個用戶,空間節省了 32 倍!

對於有大量數據的場景,若是咱們使用 bitset,那麼,能夠節省很是多的內存。

對於沒有登錄的用戶,咱們也可使用哈希算法,把對應的用戶標識哈希成一個數字 id。

bitset 很是的節省內存,假設有 1 億個用戶,也只須要 100000000/8/1024/1024 約等於 12 兆內存。

Redis 已經爲咱們提供了 SETBIT 的方法,使用起來很是的方便。

咱們能夠看看下面的例子:

咱們在 item 頁面能夠不停地使用 SETBIT 命令,設置用戶已經訪問了該頁面,也可使用 GETBIT 的方法查詢某個用戶是否訪問。

最後咱們經過 BITCOUNT 能夠統計該網頁天天的訪問數量。

優勢佔用內存更小,查詢方便,能夠指定查詢某個用戶,數據可能略有瑕疵,對於非登錄的用戶,可能不一樣的 key 映射到同一個 id,不然須要維護一個非登錄用戶的映射,有額外的開銷。

缺點若是用戶很是的稀疏,那麼佔用的內存可能比方法一更大。

使用機率算法

對於拼多多這種多個頁面均可能很是多訪問量的網站,若是所須要的數量不用那麼準確,可使用機率算法,事實上,咱們對一個網站的 UV 的統計,1 億跟 1 億零 30 萬實際上是差很少的。

在 Redis 中,已經封裝了 HyperLogLog 算法,他是一種基數評估算法。

這種算法的特徵,通常都是數據不存具體的值,而是存用來計算機率的一些相關數據。

當用戶訪問網站的時候,咱們可使用 PFADD 命令,設置對應的命令,最後咱們只要經過 PFCOUNT 就能順利計算出最終的結果,由於這個只是一個機率算法,因此可能存在 0.81% 的偏差。

優勢佔用內存極小,對於一個 key,只須要 12kb。對於拼多多這種超多用戶的特別適用。

缺點查詢指定用戶的時候,可能會出錯,畢竟存的不是具體的數據。總數也存在必定的偏差。

好了,上面就是常見的 3 種適用 Redis 統計網站用戶訪問數的方法了。


原文連接:

www.toutiao.com/i6695734985246114312/



·END·

程序員的成長之路

路雖遠,行則必至

本文原發於 同名微信公衆號「程序員的成長之路」,回覆「1024」你懂得,給個讚唄。

回覆 [ 520 ] 領取程序員最佳學習方式

回覆 [ 256 ] 查看 Java 程序員成長規劃

相關文章
相關標籤/搜索