1、社群介紹:
年糕媽媽社群作為承接年糕媽媽微信使用者到APP的平臺,為超百萬使用者 提供科學育兒服務。社群主要包含關注、推薦、發現、搜尋、育兒知識。使用者可在社群發帖、參與話題、打卡、評論、點贊、收藏、加關注。
2、社群實現難點
- feed實現,如何保證高併發低延遲
- 高併發下各種資料統計。一個頁面有帖子閱讀數、評論數、點贊數,使用者的粉絲數、關注數等
- 分頁查詢標籤下的文章列表各種排序
3、社群實現方案
總體架構圖如下:
複製程式碼
3.1 feed介紹
- feed:feed流中的每一條訊息都是Feed,朋友圈中的一個訊息就是一個Feed,微博中的一條微博就是一個Feed.
- feed流:持續更新並呈現給使用者內容的資訊流。每個人的朋友圈,微博關注頁等等都是一個Feed流。
- Timeline:Timeline是一種Feed流的型別,微博,朋友圈都是Timeline型別的Feed流
- 年糕媽媽社群的關注feed 是由關注的人釋出的帖子組成。
3.2 feed流實現模式
3.2.1 拉模式
a. 釋出帖子簡單,A釋出帖子,只需要儲存到帖子表即可
b. 關注取消流程簡單,A取消關注B:此時只需要在A的關注列表裡刪除B,並在B的粉絲列表裡刪除A。
c. A獲取feed流複雜,首先獲取A的所有關注使用者,然後獲取這些使用者所釋出的帖子並進行排序,分頁取出對應的一頁帖子。
-
優點:
1、儲存結構簡單,儲存量較小,feed資料只存一份 2、關注、釋出feed流程簡單,容易理解,適合快速開發。 複製程式碼
-
缺點:
1、獲取使用者feed流過程複雜,需多次查詢 2、不適合關注人較多的情況下的高併發查詢 複製程式碼
3.2.2 推模式
當一個使用者觸發行為(比如發帖子),自身行為記錄到行為表中,同時也對應到這個使用者的粉絲表,為每個粉絲插入一條feed。粉絲讀取feed流,只需要讀取feed流,排序即可。
-
優點
拉取feed流 業務流程簡單,查詢效能高 複製程式碼
-
缺點:
1、feed資料儲存多份,尤其大V粉絲比較多的情況下,嚴重消耗儲存資源 2、關注取消、釋出feed 業務流程變複雜 3、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
這種方式就是計數外接法,也是一種資料冗餘方法。
-
優點
1、一次查詢多種計數,一個維度計數無需多次查詢 2、查詢走主鍵索引,效率高 複製程式碼
-
缺點:
1、資料冗餘,可能出現資料不一致情況 2、在高併發下,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:清風笑