年糕媽媽社區架構實踐

一、社區介紹:

年糕媽媽社區做爲承接年糕媽媽微信用戶到APP的平臺,爲超百萬用戶 提供科學育兒服務。社區主要包含關注、推薦、發現、搜索、育兒知識。用戶可在社區發帖、參與話題、打卡、評論、點贊、收藏、加關注。mysql

二、社區實現難點

  • feed實現,如何保證高併發低延遲
  • 高併發下各類數據統計。一個頁面有帖子閱讀數、評論數、點贊數,用戶的粉絲數、關注數等
  • 分頁查詢標籤下的文章列表各類排序

三、社區實現方案

整體架構圖以下:
複製代碼

3.1 feed介紹

  • feed:feed流中的每一條消息都是Feed,朋友圈中的一個消息就是一個Feed,微博中的一條微博就是一個Feed.
  • feed流:持續更新並呈現給用戶內容的信息流。每一個人的朋友圈,微博關注頁等等都是一個Feed流。
  • Timeline:Timeline是一種Feed流的類型,微博,朋友圈都是Timeline類型的Feed流
  • 年糕媽媽社區的關注feed 是由關注的人發佈的帖子組成。

3.2 feed流實現模式

3.2.1 拉模式redis

a. 發佈帖子簡單,A發佈帖子,只須要存儲到帖子表便可sql

b. 關注取消流程簡單,A取消關注B:此時只須要在A的關注列表裏刪除B,並在B的粉絲列表裏刪除A。數據庫

c. A獲取feed流複雜,首先獲取A的全部關注用戶,而後獲取這些用戶所發佈的帖子並進行排序,分頁取出對應的一頁帖子。api

  • 優勢:緩存

    一、存儲結構簡單,存儲量較小,feed數據只存一份
    
      二、關注、發佈feed流程簡單,容易理解,適合快速開發。
    複製代碼
  • 缺點:微信

    一、獲取用戶feed流過程複雜,需屢次查詢
      二、不適合關注人較多的狀況下的高併發查詢
    複製代碼

3.2.2 推模式mybatis

當一個用戶觸發行爲(好比發帖子),自身行爲記錄到行爲表中,同時也對應到這個用戶的粉絲表,爲每一個粉絲插入一條feed。粉絲讀取feed流,只須要讀取feed流,排序便可。架構

  • 優勢併發

    拉取feed流 業務流程簡單,查詢性能高
    複製代碼
  • 缺點:

    一、feed數據存儲多份,尤爲大V粉絲比較多的狀況下,嚴重消耗存儲資源
    二、關注取消、發佈feed 業務流程變複雜
    三、feed可能延遲
    複製代碼

3.2.3 推拉模式結合

粉絲不少的用戶稱爲大V。普通用戶發佈feed時,採用推模式。離線用戶上線後定時拉取feed,後臺將大V的feed同步到該用戶的feed流中,來完成動態的拉和推。此模式避免了大V用戶發佈feed時,fee流存儲急速擴大,致使用戶查詢feed 延遲。

3.3 計數中心實現

社區展現各類數,好比帖子詳情頁有閱讀數、評論數、點贊數,用戶的粉絲數、關注數、消息數等。在計數種類多,併發高下,如何實現數據計數,常見有如下方案。

3.3.1 傳統count計數法

好比統計用戶發帖數 select count(*) from post where user_id = xxx 來統計,次方法就是 count 計數法。

  • 優勢

count計數法實現簡單,統計也比較精準,適合數量量小、低併發的業務。

  • 缺點:

一個計數一個count,實現業務每每須要屢次查詢

3.3.2 計數(外置)冗餘法

經過對社區計數業務分析,得出2個維度的計數

  • 用戶維度:關注數、粉絲數、發帖數、被贊與收藏數
  • 帖子維度:閱讀數、點贊數、評論數、收藏數

這2個維度的指標能夠經過在用戶表、帖子表中添加屬性來單獨存儲,也能夠新建2張表 用戶計數、帖子計數表存儲。

  • 比發佈帖子時,insert post,更新帖子數 update set post_num = post_num ++ where user_id = xxx
  • 查詢帖子計數時, select pv,like_num,comment_num from post where post_id = xxx

這種方式就是計數外置法,也是一種數據冗餘方法。

  • 優勢

    一、一次查詢多種計數,一個維度計數無需屢次查詢
    二、查詢走主鍵索引,效率高
    複製代碼
  • 缺點:

    一、數據冗餘,可能出現數據不一致狀況
    二、在高併發下,db 壓力增大
    複製代碼

3.3.3 計數外置改進方案

針對年糕媽媽社區業務,咱們抽象出計數服務中心(氣泡服務),經過redis緩存實時計數,定時將redis計數數據同步到db。 這樣避免了高併發給db帶來的壓力,同時提升了計數讀寫能力。

3.4 社區搜索

業務背景:社區搜索,經過輸入關鍵詞、選擇 標籤,查詢帖子、育兒知識等。

3.4.1 搜索選型:

mysql5.6.4 及以上的innoDB 也引入了全文檢索,可直接經過match 查詢,方案簡單,但內置的分詞、搜索效果不必定能知足要求。 仍是選擇了更專業的搜索引擎elasticsearch 、opensearch

3.4.2 索引同步實現

  • 全量同步

    歷史數據同步,經過掃描全表,將數據同步到索引裏
    複製代碼
  • 增量同步

    新增數據、或修改數據同步。
    方案一:在業務代碼中,將數據同步到索引
    優勢:實現簡單,數據同步分散在業務中,有業務維護
    缺點:耦合高,業務代碼混亂,沒法複用
    方案二:經過監聽數據庫的 binlog 日誌,將數據同步到索引
    優勢:解耦,可複用
    缺點:引入了額外的框架,增長了系統的複雜度
    最後咱們採用第二種方案,經過引入canal,實現binlog訂閱和數據同步
    複製代碼

3.4.3 索引查詢

  • 使用搜索引擎自帶API

    須要學習成本,每位開發都須要額外學習api使用。有沒有一種你們不須要學習就會用的工具呢

  • 自研 esqlParse

    結合 mybatis,將sql語句翻譯成搜索引擎的API,實現索引查詢。

    優勢:下降了開發學習成本,開發只須要寫sqlmapper,便可實現索引查詢

    缺點:功能還不完善,某些複雜查詢還不支持

3.5 感覺

架構都是創建在業務之上,很難一次作的最好,更多的是一步步演進而來的。本文還有不少不完善的地方,也有過其餘問題沒講解到,歡迎你們多多交流!

nicomama:清風笑

相關文章
相關標籤/搜索