在當前任何具備社交場景的app應用中,用戶之間會由於不少行爲產生關係,例如微信好友的關係,當前各類陌生人社交軟件喜歡的關係,微博粉絲與博 主的關係,當前各類直播軟件中粉絲與主播的關係。當前產生關係以後,一個用戶全部關注的用戶產生的內容就造成Feed流,這個時候須要設計一個合理的Feed流系統。mysql
如今大多數關係產生Feed流系統能夠分爲兩種實踐場景,一種是朋友圈類型,我在這裏叫作wx類型,一種是微博關注博主類型,我在這裏叫作wb類型。redis
wx類型場景,一個用戶被關注的其餘用戶的數量上限不會太大,例如微信一個用戶的好友多一點可能就幾千人,這裏能夠設計爲寫擴散模式。sql
wb類型場景,一個用戶被關注的其餘用戶的數量多是一個很大的值,例如微博一個大V博主的粉絲可能達到幾十萬、幾百萬、幾千萬這種,這裏須要設計爲讀擴散模式。數據庫
什麼是寫擴散模式,什麼是讀擴散模式?顧名思義,寫擴撒,就是將一個內容寫多份,例如一個用戶發一條朋友圈內容,除了寫入本身的朋友圈列表外,須要將這條朋友圈內容寫入全部關注他的其餘用戶的朋友圈內容列表,這樣就是一條朋友圈內容就的發佈就要寫入多個列表,這個就叫作寫擴散;讀擴撒,就是一個內容被多讀,例如一個擁有千萬粉絲的微博大V發佈了一條微博,不可能將這條內容逐一寫入到全部粉絲關注內容列表裏,這樣的一個內容寫入時間會很長,這樣會致使一次瞬間寫入量會很大,若是一個時間段有不少大V同時發佈微博,寫擴散的模式對系統的性能會有很大的損耗,這樣就只能先只寫一分內容,等到用戶下次來刷新查看的時候再來直接獲取這個大V用戶發佈的內容,這樣就是讀擴散的模式。緩存
可是,讀擴撒的設計也會有一個問題,那就是若是一個用戶關注了幾萬,幾十萬個大V博 主怎麼辦呢?難到是一次將全部關注的大V博發佈的內容所有拿出來?顯然這樣確定是不合理的,下面兩種模式下的Feed流系統設計中會有解答。微信
feed_info表結構設計架構
字段 | 類型 | 說明 |
---|---|---|
id | bigint | 主鍵id, incr id |
uid | bigint | feed內容所屬用戶id |
create_uid | bigint | feed內容建立用戶id |
feed_id | bigint | feed內容id |
type | int | feed內容類型 |
content | varbinanry(4096) | feed內容信息 |
status | tinyint | feed內容狀態, 默認status=1, status=1正常, status=2刪除 |
score_id | bigint | feed內容排序id |
create_time | datetime | feed內容建立時間 |
update_time | datetime | feed內容更新時間 |
索引設計app
uid、score_id普通索引 create_uid、feed_id惟一索引
分庫分表策略數據庫設計
根據uid來分表
feed的內容使用pb壓縮字符串, 定義feed類型字段用於標記不一樣類型的feed, 方便拓展
feed_id生成規則根據建立者用戶id生成, 非全局惟一,可是對於每個建立feed用戶惟一 score_id按照建立時間按照時間序生成,爲16位的int,用於作feed的排序
Feed list緩存設計性能
使用zset結構 key=uid val=create_uid:feed_id score=score_id list 列表只維護固定長度,淘汰老數據
Feed info緩存設計
使用hash結構 key=uid field=create_uid:feed_id val={"content": content, "type": type, "create_time": create_time, ...}
wb類型採用讀擴散模式,用戶關注的博主或主播在關注Feed列表內當用戶刷新時只是展現用戶最新的一條Feed內容,不展現全量Feed內容。此外會將已經展現給用戶的Feed內寫入用戶歷史Feed列表中,這就是讀擴散的模式。
feed_info表結構設計與寫擴散模式一致
feed list緩存與feed info緩存與寫擴散模式一致
讀取關注用戶列表offset緩存
使用kv結構 key=uid val=offset
用戶最新的Feed緩存
使用kv結構 key=uid val={"content": content, "type": type, "create_time": create_time, "score_id": score_id, "feed_id": feed_id, ...}
feed的狀態更新,例如刪除操做,經過消費kafka隊列來進行同步數據,更新緩存與數據庫。
關於每條Feed的評論、點贊、轉發不在本文所討論範圍,這些只是feed的某一屬性,不屬於feed內容自己。
這個是兩種模式下關注Feed的設計,有更好的設計歡迎提出建議,做者必定會積極採納。