使用 Redis 進行閱讀數統計並定時持久化

2022-01-15 14:18:31 字數 1637 閱讀 5419

之前,統計每篇博文的閱讀數的方式是經過篩選去重之後直接更新資料庫,併發壓力直接傳導到資料庫,假設1秒有1000個併發請求,傳統方案會在1秒內併發進行1000次資料庫更新操作。

為了降低資料庫的併發壓力,需要重新設計統計服務。思路是即使1秒有1萬個併發請求,也只是依次更新資料庫,對資料庫沒有併發壓力。

統計服務要做的事情很專一:去重+計數

去重的業務根據具體的需要來設計規則,例如乙個使用者1個小時內所有訪問都只計算一次,沒有使用者資訊的按 ip 位址或者瀏覽器標識去統計。去重就是把這些標誌去重,有多種實現方法,hash過濾,資料庫唯一性等。

這裡我們採用 redis 的hyperloglog,簡稱hll,它是乙個高效的結構,記憶體占用極小,能快速統計出所有不一樣的元素。有三個方法:

pfadd:向結構中增加乙個元素,其實hll並沒有儲存這個元素,而是按照概率論的演算法進行統計,所以 12k 記憶體就能統計 2^64 個資料,返回值為1表示該元素被統計了,反之則沒有;

pfmerge:可以把合併兩個hll

pfcount:獲取統計數,這個演算法雖然高效,但是也有弊端,就是存在誤差,在 1% 以下,只要不是非常精確的業務基本上也是可以忽略的。

我們的業務邏輯實現比較簡單,可以用博文和時間作keyhll__,再把訪問博文的使用者標誌按照規則生成乙個字串,name_ip_,用pfadd它新增進去,hll會判斷是否重複,重複的就不會統計,然後把不重複的也就是返回值為 1 的 key 儲存到集合set中,記錄下來方便遍歷。

經過去重之後我們就要統計總數並持久化到資料庫中,每篇博文在redis中對應至少乙個hll結構,建立觀察者服務不停地popset中所有的 hll 的key,然後再通過pfcount得到對應的博文的統計數。 拿到統計數之後再傳送給持久化服務處理,或者通過負載均衡交給多個持久化服務處理。

如上圖所示,部署多個 counter web服務負責接收請求,乙個 redis 服務或者集群負責統計閱讀數,多個 watcher 服務負責把統計結果取出來,交給多個資料儲存服務去持久化。

我們線上用的是 docker-swarm 集群,它本身就有負載均衡作用,所以可以省略負載均衡。

這裡之所以用set.pop(),是因為它支援併發訪問的,不會鎖 redis。如果直接遍歷所有hll key,就只能用scan全域性查詢,雖然也不會鎖住 redis,但是它不支援並行操作,對擴充套件不夠友好。

這樣架構的優點就是可以橫向擴充套件,任何地方出現效能瓶頸都能通過擴充套件解決。

參考資料

多個消費者重複消費問題

hypterloglog

hyperloglog 原理

Python爬蟲刷CSDN部落格閱讀數

本部落格僅做技術交流。刷部落格訪問量可恥。原始碼語言為python3。這裡採用西刺免費 ip 先爬取這些免費的ip,然後偽裝成這些ip訪問指定的部落格,從而增加指定文章的閱讀數。以下原始碼以博主的csdn賬號為例,將url自行修改即可訪問自己的博文。注意 刷的太快伺服器並不會增加文章的閱讀數,可自行...

csdn 閱讀數小程式v1 0

話不多說,分析一波csdn的閱讀數,是每次進入頁面記作一次,所以我們很簡單的構建乙個訪問的小爬蟲就好了,那麼開始操作。import requests import time from lxml import etree import random defpost article 下面url換成自己的...

電路設計 教你如何閱讀資料手冊

我們為什麼要看資料手冊,資料手冊又有什麼作用呢?我們能夠從中得到哪些東西呢?哪些是我們所需要的呢?下面我們以ad847晶元為例來說一說我們在工作中以及設計中需要注意哪些方面。下面是晶元的資料手冊的鏈結。ad847 high speed,low power monolithic op amp anal...