All Posts Tagged “news feed”

Build a news feed in Redis (fan-out-on-write aka Push model)

但是好像用 Cassandra 會比較適合?

--

可以用 sorted set 來儲存每個用戶的 news feed
用作品的 created_at timestamp 當 score
保持每個 set 的容量為 800 之類的

當用戶發佈了作品之後

就透過 message queue 把這個作品的 id 寫入該用戶的所有 followers 的 news feed 裡
或許也可以只寫入到所謂的 "active users"(例如七天內登入過的用戶)的 news feed 裡
因為明星級的用戶可能有很大量的 followers

news_feed:user_183 = [
user_8:song:5232, 8783421
user_2:song:432, 8509823
user_4:photo:23, 8323490
user_7:album:1232, 5323453
...
]

用 message queue 把作品 id 寫入各用戶的 news feed 時
或許也可以區分活躍用戶與非活躍用戶
活躍用戶的 task 的優先權比較高

當 A 用戶 follow 了 B 用戶之後

可以先取出 A 用戶的 news feed 的最後一個項目
看它的 created_at 是多少
然後撈出 B 用戶的比這個 created_at 還新的作品
接著寫入 A 用戶的 news feed
最後在 truncate 一下(用 ZREMRANGEBYRANK 指令)只保留 800 個項目

當用戶刪除了作品之後

可能有幾種做法:

一是在刪除之後就透過 message queue 遍歷所有 followers 的 news feed
然後把該作品刪掉(用 ZREM 指令)
但是仍然可能遇到還沒刪完就有用戶去讀自己的 news feed 的情況

二是在用戶讀自己的 news feed 的時候才檢查
假設是用 redis 的 list 或 sorted set
一開始就直接讀出 list 裡的 id 列表(當然會分頁)
然後根據 id 再去 mysql 裡撈出真正的 model(例如歌曲、專輯、照片等)
然後檢查有沒有哪些項目被標示為刪除了(假設是虛刪)
有的話就從 redis list 中刪掉
然後再撈下一個分頁的資料來補足
如果還是有應該被刪掉的資料就再重複整個過程

三是幫每個作品維護一個「哪些用戶的 news feed 會有這個作品」的 list
http://stackoverflow.com/questions/12357770/how-to-implement-user-feed-like-in-twitter-or-facebook-on-redis

當然這些方法一起用可能會更好

這裡的刪除可能不只是作品本身被刪除
也可能是 A 用戶 unfollow 了 B 用戶
所以也要把 B 用戶的作品從 A 用戶的 news feed 中刪掉
這個情況的話
似乎只能遍歷 A 用戶的 news feed 來刪掉 B 用戶的作品了?

ref:
http://highscalability.com/blog/2013/10/28/design-decisions-for-scaling-your-high-traffic-feeds.html