得物社群計數系統設計與實現

得物技術發表於2023-01-16

   1 前言

  1.1 社群數字場景

  社群業務有非常多的數字統計場景,基礎的場景主要有以下這些:

  使用者維度:釋出內容數、被點贊數、被收藏數、關注數、粉絲數、點贊內容數、收藏內容數等。

  內容維度:內容點贊數、內容閱讀數、內容分享數、內容收藏數、內容評論數等。

  標籤維度:話題內容數、特效內容數、商品內容數、品牌內容數等。

  其中部分場景還會有很多細分情況,例如內容相關的統計還會有以下場景:

  根據內容型別統計:圖文數、影片數、專欄數等。

  這樣排列組合出來的最終結果就有很多了,比如需要查詢使用者釋出的圖文內容數、使用者點讚的影片內容數等等,且這些數字一般都需要能夠支援高度精確性、高效能查詢和批次查詢等能力。

  1.2 具體案例

  具體案例可參考下列圖示:

  圖1. 個人主頁展示獲贊與收藏總數、粉絲數、關注數、釋出動態數(影片數、穿搭精選數、專欄數)。  

(圖1)

  圖2. 他人主頁展示獲贊與收藏總數、粉絲數、關注數、點贊動態數(影片數、專欄數)。  

(圖2)

  圖3. 話題主頁展示話題內容數。  

(圖3)

   2 逐漸浮現的系統風險

  2.1 歷史方案

  早期社群是直接採用Count資料表+快取的方式,這種方式在體量較小和單體服務的情況下完全沒問題,而且成本低、效能高、絕對精準,但隨著社群的體量逐漸變大、微服務拆分越來越細之後,該方案就會越來越難以支撐業務。

  2.2 系統風險

  效能瓶頸和穩定性風險:

  一方面業務明細表的體量越來越大,需要透過分庫分表來解決問題,分庫分表後再用Count聚合的方式效能就會變差。

  另一方面業務統計規則越來越複雜,使用資料庫Count的方式會使資料查詢語句越來越複雜,容易引發慢SQL從而導致資料庫不穩定。

  計數業務資料層和快取都和核心業務部分放在一起,若出現統計導致的不穩定會影響核心業務場景的使用,從而將小問題變成大問題。

  快取策略問題:

  熱點穿透問題:部分計數場景下是有新資料就刪除快取的策略,但若出現熱點內容、熱點使用者時,對應的統計資料(如點贊數、粉絲數)會頻繁刪除快取導致穿透的問題,且一般熱點內容和使用者產生的資料量比較大、查詢量也比較大,會更容易加劇問題從而引發雪崩。

  資料一致性問題:部分計數場景下是定時更新快取的策略,快取操作和MySQL操作無法在一個事務中完成,會產生不一致的問題,且在越頻繁變更的場景下差異值就會越大。

   3 計數系統設計與實現

  結合當前社群的業務現狀、體量以及考慮中長期體量增長的規劃,我們也調研了業內比較常見的一些實現方案,最終敲定透過維護一套計數中心的服務,由計數中心服務統一管理社群的數字統計的方式,整體情況大致如下:  

  3.1 寫場景

  該場景下計數中心內部主要幹三件事,主要包括資料獲取、資料處理、資料持久化。

  3.1.1 資料獲取

  資料的獲取一般有兩種方式,透過介面或透過MQ的方式,既然是平臺服務更希望對業務沒什麼侵入性,因此我們目前採用的主要是MQ的方式。

  使用MQ的情況下也有兩種方案可取,一種是業務服務根據事件觸發MQ訊息,需要業務服務先保證業務資料已經持久化且需要生產端保證訊息投遞無丟失,另一種則是直接透過訂閱業務資料表binlog的方式,這種方式可以保證業務資料已經持久化,目前得物已有DTS(資料訂閱平臺),使用起來也比較方便且可保證訊息投遞不丟失,因此我們目前更多的是採用第二種方案。

  資料獲取到後我們做一些格基礎校驗,驗證是否存在我們必要的一些欄位是否完整,同時需要驗證資料處理的冪等性防止資料重複消費等,透過訊息ID和業務唯一ID做冪等,然後把每行業務資料的各欄位格式化成變更前和變更後倆個值且可以區分出是新增還是更新(binlog訊息體就是這樣因此更加方便),之後就可以進入資料處理階段。

  3.1.2 資料處理

  拿到透過校驗和格式化後的資料,根據對應的事件和規則來判斷當前變更資料具體要做什麼操作,我們透過具體的案例來看會更直觀,如:

  場景1. 使用者A關注使用者B

  第一步,判斷出該場景下需要變更的統計數,使用者A的關注數要+1,使用者B的粉絲數要+1。

  第二步,提取需要變更的統計數的物件值,如使用者A的ID和使用者B的ID。

  第三步,格式化成統計的格式,物件ID+統計型別+統計數變化值。

  第四步,呼叫資料持久化的方法。

  場景2. 使用者A釋出的圖文內容狀態由正常變為刪除

  第一步,判斷出該場景下需要變更的統計數,使用者A釋出的圖文內容數要-1。

  第二步,提取需要變更的統計數的物件值,如使用者A的ID。

  第三步,格式化成統計的格式,物件ID+統計型別+統計數變化值。

  第四步,呼叫資料持久化的方法。

  3.1.3 資料持久化

  持久化部分主要分為兩塊,一是DB持久化,二是對於快取的更新。社群的數字統計場景主要有以下兩種情況:

  只增不減:如內容分享事件,每次事件觸發只需要給內容的分享數+1即可。

  既有增又有減:如使用者A(關注/取消關注)使用者B事件,需要給使用者A關注數(+1/-1),也需要給使用者B的粉絲數(+1/-1)。

  又因為我們透過MQ消費資料是無序的,極端情況下可能會出現先減再加的情況從而導致負數的出現,因此儲存層的欄位需要支援有符號的資料,保證最終計算的結果是正確的即可。DB層持久完成後再直接操作快取變更數字並延長有效期,若快取不存在則不處理等待讀場景有需要時再處理。

  3.2 讀場景

  讀場景整體邏輯比較簡潔,就是先查快取,快取不存在就查詢DB再寫入快取即可,可批次跨場景查詢,需要注意對負數情況的處理。

   4 總結及規劃

  4.1 總結

  計數中心是業內比較常見的做法,相對於老方案能夠降低各個業務對於複雜計數場景的維護成本,提升迭代效率和系統穩定性,獨立出來後在出現異常時業務也可做短時間降級,從而降低對核心業務的影響面。

  4.2 規劃

  目前社群已有多個場景接入計數中心,結合當前的現狀及未來的可能性,考慮後續主要最佳化方向主要有:

  降低新增場景的接入成本和效率

  計數中心服務的Owner更多的是維護系統層面的流程及穩定性,對於上游的業務邏輯並不都是很瞭解,如果需要擴大業務場景,可以考慮將統計規則部分做到可配置,將業務的部分交給業務處理,其他流程編排部分通用化。

來自 “ 得物技術 ”, 原文作者:小夏;原文連結:http://server.it168.com/a2023/0116/6786/000006786298.shtml,如有侵權,請聯絡管理員刪除。

相關文章