[譯]Reddit 是如何統(tǒng)計(jì)每個(gè)帖子的瀏覽量的

英文原文

本文翻譯自全球訪問(wèn)量排名第8位的論壇Reddit博客上的文章,講的是關(guān)于Reddit如何在海量瀏覽量下實(shí)時(shí)統(tǒng)計(jì)瀏覽量的褪那。

本文我們就來(lái)聊一聊,Reddit是如何在大規(guī)模下統(tǒng)計(jì)帖子瀏覽量的式塌。

統(tǒng)計(jì)方法

我們對(duì)統(tǒng)計(jì)瀏覽量有四個(gè)基本的要求

  • 計(jì)數(shù)必須達(dá)到實(shí)時(shí)或者接近實(shí)時(shí)博敬。
  • 每個(gè)用戶(hù)在一個(gè)時(shí)間窗口內(nèi)僅被記錄一次。
  • 帖子顯示的統(tǒng)計(jì)數(shù)量的誤差不能超過(guò)百分之幾峰尝。
  • 整個(gè)系統(tǒng)必須能在生成環(huán)境下偏窝,數(shù)秒內(nèi)完成閱讀計(jì)數(shù)的處理。

滿足上面四個(gè)條件武学,其實(shí)比想象中要復(fù)雜祭往。為了在實(shí)時(shí)統(tǒng)計(jì)的情況下保持精準(zhǔn)度,我們需要知道某一個(gè)用戶(hù)之前是否瀏覽過(guò)一篇文章火窒,所以我們需要為每一篇文章存儲(chǔ)瀏覽過(guò)它的用戶(hù)的集合硼补,并且在每次新增瀏覽時(shí)檢查該集合進(jìn)行去重復(fù)操作。

一個(gè)比較簡(jiǎn)單的解決方案是熏矿,為每篇文章維護(hù)一個(gè)哈希表括勺,用文章ID作為key,去重的userid的集合(set數(shù)據(jù)結(jié)構(gòu))作為value曲掰。

這種方案在文章數(shù)量和閱讀數(shù)比較小的情況下疾捍,還能很好的運(yùn)行,但當(dāng)數(shù)據(jù)量到達(dá)大規(guī)模時(shí)栏妖,它就不適用了乱豆。尤其是該文章變成了熱門(mén)文章,閱讀數(shù)迅速增長(zhǎng)吊趾,有些受歡迎的文章的閱讀者數(shù)量超過(guò)百萬(wàn)級(jí)別宛裕,想象一下維護(hù)一個(gè)超過(guò)百萬(wàn)的unqine userId的集合在內(nèi)存中的瑟啃,還有經(jīng)受住不斷的查詢(xún),集合中的用戶(hù)是否存在揩尸。

自從我們決定不提供100%精準(zhǔn)的數(shù)據(jù)后蛹屿,我們開(kāi)始考慮使用幾種不同的基數(shù)估計(jì)算法。我們綜合考慮下選出量?jī)蓚€(gè)可以滿足需求的算法:

  • 線性概率計(jì)算方法岩榆,它非常精確错负,但是需要的內(nèi)存數(shù)量是根據(jù)用戶(hù)數(shù)線性增長(zhǎng)的。
  • 基于HyperLogLog (HLL)的計(jì)算方法勇边,HLL的內(nèi)存增長(zhǎng)是非線性的犹撒,但是統(tǒng)計(jì)的精準(zhǔn)度和線性概率就不是同一級(jí)別的了。

為了更好的理解基于HLL的計(jì)算方法粒褒,究竟能夠節(jié)省多少內(nèi)存识颊,我們這里使用一個(gè)例子∞确兀考慮到r/pics文章祥款,在本文開(kāi)頭提及,該文章收到了超過(guò)一百萬(wàn)用戶(hù)的瀏覽過(guò)月杉,如果我們存儲(chǔ)一百萬(wàn)個(gè)唯一的用戶(hù)ID刃跛,每一個(gè)id占用8個(gè)字節(jié),那么僅僅一篇文章就需要8mb的空間存儲(chǔ)沙合!對(duì)照著HLL所需要的存儲(chǔ)空間就非常少了,在這個(gè)例子中使用HLL計(jì)算方法僅需要 12kb的空間也就是第一種方法的0.15%跌帐。

(This article on High Scalability 這篇文章講解了上面的兩種算法.)

有很多的HLL實(shí)現(xiàn)是基于上面兩種算法的結(jié)合而成的首懈,也就是一開(kāi)始統(tǒng)計(jì)數(shù)量少的情況下使用線性概率方法,當(dāng)數(shù)量達(dá)到一定閾值時(shí)谨敛,切換為HLL方法究履。這種混合方法非常有用,不但能夠?yàn)樾×繑?shù)據(jù)集提供精準(zhǔn)性脸狸,也能為大量數(shù)據(jù)節(jié)省存儲(chǔ)空間最仑。該種實(shí)現(xiàn)方式的細(xì)節(jié)請(qǐng)參閱論文(Google’s HyperLogLog++ paper

HLL算法的實(shí)現(xiàn)是相當(dāng)標(biāo)準(zhǔn)的,這里有三種不同的實(shí)現(xiàn)方式炊甲,要注意的是泥彤,基于內(nèi)存存儲(chǔ)方案的HLL,這里我們只考慮Java和Scale兩種實(shí)現(xiàn)

  • Twitter的Algebird庫(kù)卿啡,Scala實(shí)現(xiàn)吟吝,Algebird的文檔撰寫(xiě)非常好,但是關(guān)于它是如何實(shí)現(xiàn)HLL的颈娜,不是很容易理解剑逃。
  • stream-lib庫(kù)中的HyperLogLog++實(shí)現(xiàn)浙宜,Java編寫(xiě)。 stream-lib代碼的文檔化做的很好蛹磺,但我們對(duì)如何適當(dāng)調(diào)優(yōu)它粟瞬,還是有些困惑的。
  • Redis的HLL實(shí)現(xiàn)(我們最終的選擇)萤捆,我們覺(jué)得Redis的實(shí)現(xiàn)不管從文檔完善程度還是配置和提供的API接口裙品,來(lái)說(shuō)做的都非常好。另外的加分點(diǎn)是鳖轰,使用Redis可以減少我們對(duì)CPU和內(nèi)存性能的擔(dān)憂清酥。

Reddit的數(shù)據(jù)管道,主要都是使用Apache Kafka的蕴侣。每當(dāng)一個(gè)用戶(hù)瀏覽一篇文章時(shí)焰轻,就會(huì)觸發(fā)一個(gè)事件并且被發(fā)送到事件收集服務(wù)器,然后批量的將這些事件發(fā)送打kafka中進(jìn)行持久化昆雀。

Reddit的瀏覽統(tǒng)計(jì)系統(tǒng)辱志,分為兩個(gè)順序執(zhí)行的組成部分,其中的第一部分是狞膘,被稱(chēng)為Nazarkafka隊(duì)列『消費(fèi)者』(consumer) 揩懒,它會(huì)從kafka中讀取事件,然后將這些事件通過(guò)特定的條件進(jìn)行過(guò)濾挽封,判斷改事件是否應(yīng)該被算作一次文章閱讀計(jì)數(shù)已球,它被稱(chēng)為『NAZAR』是因?yàn)樵谙到y(tǒng)中它有作為『眼鏡』的用處,識(shí)別出哪些事件是不應(yīng)該被加入到統(tǒng)計(jì)中的辅愿。Nazar使用Redis 維護(hù)狀態(tài)還有一個(gè)事件不被計(jì)數(shù)的潛在原因智亮,這個(gè)原因可能是用戶(hù)短時(shí)間內(nèi)重復(fù)瀏覽統(tǒng)一文章。Nazar會(huì)在事件被發(fā)送回kafka時(shí)点待,為事件添加一個(gè)標(biāo)識(shí)位阔蛉,根據(jù)該事件是否被加入到計(jì)數(shù)當(dāng)中的布爾值。

統(tǒng)計(jì)系統(tǒng)的第二部是一個(gè)稱(chēng)為Abacus 的kafka『消費(fèi)者』它會(huì)真正的統(tǒng)計(jì)瀏覽量癞埠,并且讓瀏覽量數(shù)據(jù)可以在整站和客戶(hù)端上顯示状原, 它接收從Nazar發(fā)送出來(lái)的事件消息,然后根據(jù)該消息中包含著標(biāo)識(shí)值(Nazar中處理的)來(lái)判斷這個(gè)事件是否算做一次計(jì)數(shù)苗踪,如果事件被計(jì)數(shù)颠区,Abacus會(huì)首先檢查這個(gè)事件中文章的HLL計(jì)數(shù)是否存在于Redis中,如果存在通铲,Abacus會(huì)發(fā)送一個(gè)PFADD請(qǐng)求給Redis瓦呼,如果不存在,Abacus會(huì)發(fā)生一個(gè)請(qǐng)求到Cassandra集群,Cassandra集群會(huì)持久化HLL 計(jì)數(shù)和真實(shí)的原始計(jì)數(shù)數(shù)據(jù)央串,然后再發(fā)送一個(gè)SET請(qǐng)求到Redis磨澡,這個(gè)過(guò)程通常出現(xiàn)在用戶(hù)閱讀一個(gè)已經(jīng)被Redis剔除的就文章的情況下發(fā)送。

為了讓維護(hù)一個(gè)在Redis可能被剔除的舊文章质和,Abacus會(huì)定期的稳摄,從Redis中將HLL過(guò)濾數(shù)據(jù),包括每篇文章的計(jì)數(shù)饲宿,全部寫(xiě)入到Cassandra集群中厦酬,當(dāng)然為了避免集群過(guò)載,這個(gè)步驟會(huì)分為每篇文章10秒一組批次進(jìn)行寫(xiě)入瘫想。下圖就是整個(gè)過(guò)程的流程圖仗阅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市国夜,隨后出現(xiàn)的幾起案子减噪,更是在濱河造成了極大的恐慌,老刑警劉巖车吹,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筹裕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡窄驹,警方通過(guò)查閱死者的電腦和手機(jī)朝卒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)乐埠,“玉大人抗斤,你說(shuō)我怎么就攤上這事≌筛溃” “怎么了瑞眼?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)扯罐。 經(jīng)常有香客問(wèn)我负拟,道長(zhǎng)烦衣,這世上最難降的妖魔是什么歹河? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮花吟,結(jié)果婚禮上秸歧,老公的妹妹穿的比我還像新娘。我一直安慰自己衅澈,他們只是感情好键菱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著今布,像睡著了一般经备。 火紅的嫁衣襯著肌膚如雪拭抬。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天侵蒙,我揣著相機(jī)與錄音造虎,去河邊找鬼。 笑死纷闺,一個(gè)胖子當(dāng)著我的面吹牛算凿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播犁功,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼氓轰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了浸卦?” 一聲冷哼從身側(cè)響起署鸡,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镐躲,沒(méi)想到半個(gè)月后储玫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萤皂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年撒穷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片裆熙。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡端礼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出入录,到底是詐尸還是另有隱情蛤奥,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布僚稿,位于F島的核電站凡桥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蚀同。R本人自食惡果不足惜缅刽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蠢络。 院中可真熱鬧衰猛,春花似錦、人聲如沸刹孔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至卦睹,卻和暖如春畦戒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背结序。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工兢交, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人笼痹。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓配喳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親凳干。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晴裹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容