年糕媽媽社區做爲承接年糕媽媽微信用戶到APP的平臺,爲超百萬用戶 提供科學育兒服務。社區主要包含關注、推薦、發現、搜索、育兒知識。用戶可在社區發帖、參與話題、打卡、評論、點贊、收藏、加關注。mysql
整體架構圖以下:
複製代碼
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.1 傳統count計數法
好比統計用戶發帖數 select count(*) from post where user_id = xxx 來統計,次方法就是 count 計數法。
count計數法實現簡單,統計也比較精準,適合數量量小、低併發的業務。
一個計數一個count,實現業務每每須要屢次查詢
3.3.2 計數(外置)冗餘法
經過對社區計數業務分析,得出2個維度的計數
這2個維度的指標能夠經過在用戶表、帖子表中添加屬性來單獨存儲,也能夠新建2張表 用戶計數、帖子計數表存儲。
這種方式就是計數外置法,也是一種數據冗餘方法。
優勢
一、一次查詢多種計數,一個維度計數無需屢次查詢
二、查詢走主鍵索引,效率高
複製代碼
缺點:
一、數據冗餘,可能出現數據不一致狀況
二、在高併發下,db 壓力增大
複製代碼
3.3.3 計數外置改進方案
針對年糕媽媽社區業務,咱們抽象出計數服務中心(氣泡服務),經過redis緩存實時計數,定時將redis計數數據同步到db。 這樣避免了高併發給db帶來的壓力,同時提升了計數讀寫能力。
業務背景:社區搜索,經過輸入關鍵詞、選擇 標籤,查詢帖子、育兒知識等。
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,便可實現索引查詢
缺點:功能還不完善,某些複雜查詢還不支持
架構都是創建在業務之上,很難一次作的最好,更多的是一步步演進而來的。本文還有不少不完善的地方,也有過其餘問題沒講解到,歡迎你們多多交流!
nicomama:清風笑