上回寫了使用Redis實現關注關係,此次說說使用Redis實現Timeline。html
Timeline的實現通常有推模式、拉模式、推拉結合這幾種。
推模式:某人發佈內容以後推送給全部粉絲,空間換時間,瓶頸在寫入;
拉模式:粉絲從本身的關注列表中讀取內容,時間換空間,瓶頸在讀取;
推拉結合:某人發佈內容後推送給活躍粉絲
,不活躍粉絲則使用拉取。web
目前只討論推模式,考慮單個feed內容實體存入散列(hashes)、每一個用戶的timeline列表存入列表(lists)。redis
發佈者發佈內容後,生成惟一feedID,以feedID爲key存入hashes。
首先從發佈者的粉絲表裏獲取全部粉絲,再進行推送。segmentfault
邏輯以下:post
// 使用Redis INCR操做,生成惟一postID $feedID = $redis->INCR("global:postID"); // 存入Hashes $feedData = [ 'userID' => 1, 'timestamp' => '1458680000', 'content' => '這是一條tweet', 'platform' => 'web', ]; $redis->HSET($feedID, $feedData); // 寫入發佈者本身的已發佈列表 $redis->LPUSH("{$userID}:tweets", $feedID); // 寫入發佈者本身的timeline $redis->LPUSH("{$userID}:timeline", $feedID); // 獲取發佈者粉絲列表 $follwerIDs = $redis->SMEMBERS("1:followers"); // 寫入 foreach ($follwerIDs as $followerID) { $redis->LPUSH("{$followerID}:timeline", $feedID); }
某用戶登錄以後,獲取timeline Lists中的值,再從Hashes取數據進行處理。code
$feedIDs = $redis->LRANGE("{$userID}:timeline", 0, 30); //取30條數據 foreach ($feedIDs as $feedID) { $feedData = $redis->HGETALL($feedID); // TODO:進一步進行處理、整合等操做。 }
當發佈者刪除某條消息後,循環全部粉絲列表,並執行刪除操做。orm
// 從發佈者本身的已發佈刪除掉 $redis->LREM("{$userID}:tweets", 1, $feedID); // 從發佈者本身的timeline刪除掉 $redis->LREM("{$userID}:timeline", 1, $feedID); // 獲取發佈者粉絲列表 $follwerIDs = $redis->SMEMBERS("1:followers"); // 刪除 foreach ($follwerIDs as $followerID) { $redis->LREM("{$followerID}:timeline", 1, $feedID); }
timeline從某種角度來講是臨時性的,若是年代久遠,可沒必要操做粉絲的timeline。htm
Timeline系統提及來會很複雜,也不可能只靠Redis去實現。本文只是一個大致的思路,應對小數據量基本足夠。blog
博客:http://blog.lovemydeer.com/2016/03/19/redis-timeline.htmlget
[1]{:target="_blank"}: http://www.javashuo.com/article/p-romzljcm-v.html