Feed流系統設計實踐(一)

關係內容Feed流

關係內容Feed流簡單介紹

在當前任何具備社交場景的app應用中,用戶之間會由於不少行爲產生關係,例如微信好友的關係,當前各類陌生人社交軟件喜歡的關係,微博粉絲與博 主的關係,當前各類直播軟件中粉絲與主播的關係。當前產生關係以後,一個用戶全部關注的用戶產生的內容就造成Feed流,這個時候須要設計一個合理的Feed流系統。mysql

如今大多數關係產生Feed流系統能夠分爲兩種實踐場景,一種是朋友圈類型,我在這裏叫作wx類型,一種是微博關注博主類型,我在這裏叫作wb類型。redis

wx類型場景,一個用戶被關注的其餘用戶的數量上限不會太大,例如微信一個用戶的好友多一點可能就幾千人,這裏能夠設計爲寫擴散模式。sql

wb類型場景,一個用戶被關注的其餘用戶的數量多是一個很大的值,例如微博一個大V博主的粉絲可能達到幾十萬、幾百萬、幾千萬這種,這裏須要設計爲讀擴散模式。數據庫

什麼是寫擴散模式,什麼是讀擴散模式?顧名思義,寫擴撒,就是將一個內容寫多份,例如一個用戶發一條朋友圈內容,除了寫入本身的朋友圈列表外,須要將這條朋友圈內容寫入全部關注他的其餘用戶的朋友圈內容列表,這樣就是一條朋友圈內容就的發佈就要寫入多個列表,這個就叫作寫擴散;讀擴撒,就是一個內容被多讀,例如一個擁有千萬粉絲的微博大V發佈了一條微博,不可能將這條內容逐一寫入到全部粉絲關注內容列表裏,這樣的一個內容寫入時間會很長,這樣會致使一次瞬間寫入量會很大,若是一個時間段有不少大V同時發佈微博,寫擴散的模式對系統的性能會有很大的損耗,這樣就只能先只寫一分內容,等到用戶下次來刷新查看的時候再來直接獲取這個大V用戶發佈的內容,這樣就是讀擴散的模式。緩存

可是,讀擴撒的設計也會有一個問題,那就是若是一個用戶關注了幾萬,幾十萬個大V博 主怎麼辦呢?難到是一次將全部關注的大V博發佈的內容所有拿出來?顯然這樣確定是不合理的,下面兩種模式下的Feed流系統設計中會有解答。微信

關係內容Feed流系統設計

1. wx類型關係類容Feed流系統

Feed系統架構圖

圖片描述

Feed寫入和查詢時序圖

圖片描述

Feed寫入流程圖

圖片描述

Feed查詢流程圖

圖片描述

mysql數據庫設計

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內容設計

feed的內容使用pb壓縮字符串, 定義feed類型字段用於標記不一樣類型的feed, 方便拓展

feed_id與score_id生成規則

feed_id生成規則根據建立者用戶id生成, 非全局惟一,可是對於每個建立feed用戶惟一
score_id按照建立時間按照時間序生成,爲16位的int,用於作feed的排序

redis緩存設計

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, ...}

2. wb類型關係類容Feed流系統

wb類型採用讀擴散模式,用戶關注的博主或主播在關注Feed列表內當用戶刷新時只是展現用戶最新的一條Feed內容,不展現全量Feed內容。此外會將已經展現給用戶的Feed內寫入用戶歷史Feed列表中,這就是讀擴散的模式。

Feed系統架構圖

圖片描述

Feed寫入和查詢時序圖

圖片描述

Feed寫入流程圖

圖片描述

Feed查詢流程圖

圖片描述

mysql數據庫設計

feed_info表結構設計與寫擴散模式一致

redis緩存設計

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的設計,有更好的設計歡迎提出建議,做者必定會積極採納。

相關文章
相關標籤/搜索