得物社區(qū)計(jì)數(shù)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)
1、前言
1.1 社區(qū)數(shù)字場景
社區(qū)業(yè)務(wù)有非常多的數(shù)字統(tǒng)計(jì)場景,基礎(chǔ)的場景主要有以下這些:
- 用戶維度:發(fā)布內(nèi)容數(shù)、被點(diǎn)贊數(shù)、被收藏?cái)?shù)、關(guān)注數(shù)、粉絲數(shù)、點(diǎn)贊內(nèi)容數(shù)、收藏內(nèi)容數(shù)等。
- 內(nèi)容維度:內(nèi)容點(diǎn)贊數(shù)、內(nèi)容閱讀數(shù)、內(nèi)容分享數(shù)、內(nèi)容收藏?cái)?shù)、內(nèi)容評論數(shù)等。
- 標(biāo)簽維度:話題內(nèi)容數(shù)、特效內(nèi)容數(shù)、商品內(nèi)容數(shù)、品牌內(nèi)容數(shù)等。
其中部分場景還會有很多細(xì)分情況,例如內(nèi)容相關(guān)的統(tǒng)計(jì)還會有以下場景:
- 根據(jù)內(nèi)容類型統(tǒng)計(jì):圖文數(shù)、視頻數(shù)、專欄數(shù)等。
這樣排列組合出來的最終結(jié)果就有很多了,比如需要查詢用戶發(fā)布的圖文內(nèi)容數(shù)、用戶點(diǎn)贊的視頻內(nèi)容數(shù)等等,且這些數(shù)字一般都需要能夠支持高度精確性、高性能查詢和批量查詢等能力。
1.2 具體案例
具體案例可參考下列圖示:
- 圖1. 個(gè)人主頁展示獲贊與收藏總數(shù)、粉絲數(shù)、關(guān)注數(shù)、發(fā)布動態(tài)數(shù)(視頻數(shù)、穿搭精選數(shù)、專欄數(shù))。
(圖1)
- 圖2. 他人主頁展示獲贊與收藏總數(shù)、粉絲數(shù)、關(guān)注數(shù)、點(diǎn)贊動態(tài)數(shù)(視頻數(shù)、專欄數(shù))。
(圖2)
- 圖3. 話題主頁展示話題內(nèi)容數(shù)。?
(圖3)
2、逐漸浮現(xiàn)的系統(tǒng)風(fēng)險(xiǎn)
2.1 歷史方案
2.2 系統(tǒng)風(fēng)險(xiǎn)
- 性能瓶頸和穩(wěn)定性風(fēng)險(xiǎn):
- 一方面業(yè)務(wù)明細(xì)表的體量越來越大,需要通過分庫分表來解決問題,分庫分表后再用Count聚合的方式性能就會變差。
- 另一方面業(yè)務(wù)統(tǒng)計(jì)規(guī)則越來越復(fù)雜,使用數(shù)據(jù)庫Count的方式會使數(shù)據(jù)查詢語句越來越復(fù)雜,容易引發(fā)慢SQL從而導(dǎo)致數(shù)據(jù)庫不穩(wěn)定。
- 計(jì)數(shù)業(yè)務(wù)數(shù)據(jù)層和緩存都和核心業(yè)務(wù)部分放在一起,若出現(xiàn)統(tǒng)計(jì)導(dǎo)致的不穩(wěn)定會影響核心業(yè)務(wù)場景的使用,從而將小問題變成大問題。
- 緩存策略問題:
- 熱點(diǎn)穿透問題:部分計(jì)數(shù)場景下是有新數(shù)據(jù)就刪除緩存的策略,但若出現(xiàn)熱點(diǎn)內(nèi)容、熱點(diǎn)用戶時(shí),對應(yīng)的統(tǒng)計(jì)數(shù)據(jù)(如點(diǎn)贊數(shù)、粉絲數(shù))會頻繁刪除緩存導(dǎo)致穿透的問題,且一般熱點(diǎn)內(nèi)容和用戶產(chǎn)生的數(shù)據(jù)量比較大、查詢量也比較大,會更容易加劇問題從而引發(fā)雪崩。
- 數(shù)據(jù)一致性問題:部分計(jì)數(shù)場景下是定時(shí)更新緩存的策略,緩存操作和MySQL操作無法在一個(gè)事務(wù)中完成,會產(chǎn)生不一致的問題,且在越頻繁變更的場景下差異值就會越大。
3、計(jì)數(shù)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)
結(jié)合當(dāng)前社區(qū)的業(yè)務(wù)現(xiàn)狀、體量以及考慮中長期體量增長的規(guī)劃,我們也調(diào)研了業(yè)內(nèi)比較常見的一些實(shí)現(xiàn)方案,最終敲定通過維護(hù)一套計(jì)數(shù)中心的服務(wù),由計(jì)數(shù)中心服務(wù)統(tǒng)一管理社區(qū)的數(shù)字統(tǒng)計(jì)的方式,整體情況大致如下:
3.1 寫場景
該場景下計(jì)數(shù)中心內(nèi)部主要干三件事,主要包括數(shù)據(jù)獲取、數(shù)據(jù)處理、數(shù)據(jù)持久化。
3.1.1 數(shù)據(jù)獲取
數(shù)據(jù)的獲取一般有兩種方式,通過接口或通過MQ的方式,既然是平臺服務(wù)更希望對業(yè)務(wù)沒什么侵入性,因此我們目前采用的主要是MQ的方式。
使用MQ的情況下也有兩種方案可取,一種是業(yè)務(wù)服務(wù)根據(jù)事件觸發(fā)MQ消息,需要業(yè)務(wù)服務(wù)先保證業(yè)務(wù)數(shù)據(jù)已經(jīng)持久化且需要生產(chǎn)端保證消息投遞無丟失,另一種則是直接通過訂閱業(yè)務(wù)數(shù)據(jù)表binlog的方式,這種方式可以保證業(yè)務(wù)數(shù)據(jù)已經(jīng)持久化,目前得物已有DTS(數(shù)據(jù)訂閱平臺),使用起來也比較方便且可保證消息投遞不丟失,因此我們目前更多的是采用第二種方案。
數(shù)據(jù)獲取到后我們做一些格基礎(chǔ)校驗(yàn),驗(yàn)證是否存在我們必要的一些字段是否完整,同時(shí)需要驗(yàn)證數(shù)據(jù)處理的冪等性防止數(shù)據(jù)重復(fù)消費(fèi)等,通過消息ID和業(yè)務(wù)唯一ID做冪等,然后把每行業(yè)務(wù)數(shù)據(jù)的各字段格式化成變更前和變更后倆個(gè)值且可以區(qū)分出是新增還是更新(binlog消息體就是這樣因此更加方便),之后就可以進(jìn)入數(shù)據(jù)處理階段。
3.1.2 數(shù)據(jù)處理
拿到通過校驗(yàn)和格式化后的數(shù)據(jù),根據(jù)對應(yīng)的事件和規(guī)則來判斷當(dāng)前變更數(shù)據(jù)具體要做什么操作,我們通過具體的案例來看會更直觀,如:
場景1. 用戶A關(guān)注用戶B
- 第一步,判斷出該場景下需要變更的統(tǒng)計(jì)數(shù),用戶A的關(guān)注數(shù)要+1,用戶B的粉絲數(shù)要+1。
- 第二步,提取需要變更的統(tǒng)計(jì)數(shù)的對象值,如用戶A的ID和用戶B的ID。
- 第三步,格式化成統(tǒng)計(jì)的格式,對象ID+統(tǒng)計(jì)類型+統(tǒng)計(jì)數(shù)變化值。
- 第四步,調(diào)用數(shù)據(jù)持久化的方法。
場景2. 用戶A發(fā)布的圖文內(nèi)容狀態(tài)由正常變?yōu)閯h除
- 第一步,判斷出該場景下需要變更的統(tǒng)計(jì)數(shù),用戶A發(fā)布的圖文內(nèi)容數(shù)要-1。
- 第二步,提取需要變更的統(tǒng)計(jì)數(shù)的對象值,如用戶A的ID。
- 第三步,格式化成統(tǒng)計(jì)的格式,對象ID+統(tǒng)計(jì)類型+統(tǒng)計(jì)數(shù)變化值。
- 第四步,調(diào)用數(shù)據(jù)持久化的方法。
3.1.3 數(shù)據(jù)持久化
持久化部分主要分為兩塊,一是DB持久化,二是對于緩存的更新。社區(qū)的數(shù)字統(tǒng)計(jì)場景主要有以下兩種情況:
- 只增不減:如內(nèi)容分享事件,每次事件觸發(fā)只需要給內(nèi)容的分享數(shù)+1即可。
- 既有增又有減:如用戶A(關(guān)注/取消關(guān)注)用戶B事件,需要給用戶A關(guān)注數(shù)(+1/-1),也需要給用戶B的粉絲數(shù)(+1/-1)。
又因?yàn)槲覀兺ㄟ^MQ消費(fèi)數(shù)據(jù)是無序的,極端情況下可能會出現(xiàn)先減再加的情況從而導(dǎo)致負(fù)數(shù)的出現(xiàn),因此存儲層的字段需要支持有符號的數(shù)據(jù),保證最終計(jì)算的結(jié)果是正確的即可。DB層持久完成后再直接操作緩存變更數(shù)字并延長有效期,若緩存不存在則不處理等待讀場景有需要時(shí)再處理。
3.2 讀場景
讀場景整體邏輯比較簡潔,就是先查緩存,緩存不存在就查詢DB再寫入緩存即可,可批量跨場景查詢,需要注意對負(fù)數(shù)情況的處理。
4、總結(jié)及規(guī)劃
4.1 總結(jié)
計(jì)數(shù)中心是業(yè)內(nèi)比較常見的做法,相對于老方案能夠降低各個(gè)業(yè)務(wù)對于復(fù)雜計(jì)數(shù)場景的維護(hù)成本,提升迭代效率和系統(tǒng)穩(wěn)定性,獨(dú)立出來后在出現(xiàn)異常時(shí)業(yè)務(wù)也可做短時(shí)間降級,從而降低對核心業(yè)務(wù)的影響面。
4.2 規(guī)劃
目前社區(qū)已有多個(gè)場景接入計(jì)數(shù)中心,結(jié)合當(dāng)前的現(xiàn)狀及未來的可能性,考慮后續(xù)主要優(yōu)化方向主要有:
降低新增場景的接入成本和效率 | 計(jì)數(shù)中心服務(wù)的Owner更多的是維護(hù)系統(tǒng)層面的流程及穩(wěn)定性,對于上游的業(yè)務(wù)邏輯并不都是很了解,如果需要擴(kuò)大業(yè)務(wù)場景,可以考慮將統(tǒng)計(jì)規(guī)則部分做到可配置,將業(yè)務(wù)的部分交給業(yè)務(wù)處理,其他流程編排部分通用化。 |