常用Feed流架構實現


業務中很多需求都會用到類似feed流的架構。
例如

  • 微信朋友圈
  • 微博
  • 動態
  • 1對N消息。

一般feed流的架構實現有下面幾種。
假如現在的業務場景是微博,然后當前的數據情況是:

用戶A關注了用戶B和C,用戶D關注了用戶B
用戶B發了微博A,B,用戶C發了微博C,D

1. 拉

數據表

  • 微博表(字段有:微博ID,微博內容,發布人)

代碼邏輯:

  1. 用戶 B發布微博接口,插入記錄到微博表,只有一行記錄
  2. 用戶A獲取我關注的用戶的微博接口:
    1. 獲取當前登錄用戶關注的用戶,例如A關注的用戶B和C
    2. 獲取B和C發布的所有微博,
    3. 按時間倒序排列,分頁,返回

優缺點:

  • 實現簡單
  • 空間占用較少,一條微博只用一條數據庫記錄
  • 數據量大的情況下, 第2個接口查詢較慢(需要用臨時表,而且查詢數據較多)

2.推

數據表

  • 微博表(字段有:微博ID,微博內容,發布人)
  • feed流表(字段有:微博ID,發布時間,接收人)

代碼邏輯:

  1. 發布微博接口
    1. 插入記錄到微博表
    2. 獲取當前用戶粉絲用戶列表,假如當前用戶是B,那就是獲取A和D
    3. 插入2行記錄到feed流表
      1. 接收人=A,微博ID=剛才的微博表ID
      2. 接收人=B,微博ID=剛才的微博表ID
  2. 用戶A獲取我關注的用戶的微博接口:
    1. 查詢feed流表,找到接收人=A的記錄,按發布時間倒序排,分頁,返回

優缺點:

  • 實現較復雜
  • 空間占用較多,一條微博需要插入1+N條記錄(N是粉絲用戶數)。如果N是幾十w或者幾百w,對數據庫壓力非常大,包括空間占用,插入或刪除耗時,索引建立等。
  • 第2個接口可以用索引,所以查詢很快,。

3.推+拉

上面兩種方案都有優缺點,當對讀的要求很高,同時用戶粉絲數很大,就要想辦法優化,推+拉是其中一種方案。
具體方法是區分用戶:

  • 對於經常讀取的用戶,采用推方案,保證讀取的性能
  • 對於不常讀取的用戶,采用拉方案,降低存儲壓力

從產品的角度看,有很多種方法可以區分用戶是否屬於經常讀,這里提供其中一個可行的方案:

4. 區分活躍用戶的推+拉

數據表

  • 微博表(字段有:微博ID,微博內容,發布人)
  • feed流表(字段有:微博ID,發布時間,接收人)
  • 活躍用戶表(字段有:用戶ID,是否活躍,最新登錄時間)

代碼邏輯:

  1. 發布微博接口

    1. 插入記錄到微博表
    2. 獲取當前用戶活躍粉絲用戶列表,假如當前用戶是B,那就是獲取A和D,其中A是活躍用戶,D是非活躍,那就只獲取A。SQL可以用exists,例如:select * from fans where exists (select * from 活躍表 where 是否活躍=1)
    3. 插入1行記錄到feed流表(D不是活躍用戶,就不插入了)
      1. 接收人=A,微博ID=剛才的微博表ID
  2. 用戶A獲取我關注的用戶的微博接口:

    1. 查詢feed流表,找到接收人=A的記錄,按發布時間倒序排,分頁,返回
  3. APP啟動接口(每次APP啟動,發送一個請求到后端)

    1. 如果用戶是活躍用戶,更新用戶最新登錄時間
    2. 如果不是,通過拉方式為用戶補發feed流:
      1. 獲取用戶所有關注的用戶
      2. 獲取這些用戶發的微博
      3. 把這些微博ID插入到用戶的feed流表(要避免重復插入)
  4. 定時任務

    1. 每天把最新登錄時間小於1天前的用戶,設置為非活躍

優缺點:

  • 第2個接口可以用索引,所以查詢很快。
  • 數據庫壓力降低。因為一般粉絲中活躍用戶只有小部分,同時補發的時候,可以只補發最新的N條微博,進一步節省空間,當然這些要和產品經理制定好規則。
  • 邏輯較復雜
  • 因為補發feed流需要一定時間,所以這期間用戶只能拉到舊的微博

5.總結

  • 如果想簡單做,而且對讀取要求不高,用拉方式就可以了
  • 如果對讀取要求高,同時粉絲數不多,例如朋友圈,最多就幾千個朋友,建議用推方式
  • 如果粉絲數很多,例如微博,動輒幾十萬到幾千萬粉絲的,建議用推+拉方式

未經允許,請不要轉載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM