程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php + Redis 寫的類似於新浪微博的feed系統

php + Redis 寫的類似於新浪微博的feed系統

編輯:關於PHP編程

php + Redis 寫的類似於新浪微博的feed系統


最近接了一個feed系統的外包,類似於微博那種!客戶端是ios和android,服務器用的php,數據庫用的是redis。分享下服務器和數據庫部分的功能!希望對大家有幫助。     關於redis的介紹,大家可以看這個百度百科 !       首先是用戶基本信息部分,包含賬號,昵稱,簽名,公司還有頭像,我們使用redis的hash結構(一種類似於map鍵值對的數據結構)結構如下:(大家在做的時候,還是用hgetAll的命令,這樣只會有一次的網絡請求),注意只是基本信息,諸如玩家的粉絲,關注和帖子,我們采取其他的數據結構體來存儲!     public function updateUInfo($name,$sign,$head,$from) {     $redisCli = new Redis(ServerConfig::$redisAddr);     $redisCli->hSet("user:$this->uid",'sign',$sign);     $redisCli->hSet("user:$this->uid","name",$name);     $redisCli->hSet("user:$this->uid","head",$head);     $redisCli->hSet("user:$this->uid","from",$from);          $redisCli->set("account:$name:uid",$this->uid);  }         核心1:關注和粉絲系統!每個用戶都要維護自己的關注和粉絲系統!分別用user:$uid:followings 和 user:$uid:followers兩個字段體現,使用的是redis的集合類型(相當於java裡面的hashSet和stl中的set,集合中的元素唯一)!        收聽某用戶(mutli是redis提供的一種事務,這樣,就可以避免產生諸如,你收聽了某人,而猶豫異常,別人的粉絲中缺沒有你的現象)     public function addFollowing($tid) {         $redisCli = new Redis(ServerConfig::$redisAddr);          if($redisCli->sismember("user:$this->uid:followings",$tid) == 1)     {         return ;     }          $redisCli->multi();          $redisCli->sAdd("user:$this->uid:followings",$tid);     $redisCli->sAdd("user:$tid:followers",$this->uid);          $redisCli->exec();   }     取消收聽某用戶:     public function removeFollowings($tid) {     $redisCli = new Redis(ServerConfig::$redisAddr);          if($redisCli->sismember("user:$this->uid:followings",$tid) == 0)     {         return ;     }          $redisCli->multi();     $redisCli->sRem("user:$this->uid:followings",$tid);     $redisCli->sRem("user:$tid:followers",$this->uid);     $redisCli->exec();     }       核心2:下面談談帖子的更新:      首先是帖子的基本數據結構,同上面用戶的基本數據結構,采用redis的hash結構:       class post {     //put your code here          private $postId = 0;          private $timeStamp = 0;          private $uid = 0;                private $content = "";           private $subPosts = array();          private $originPostId = -1;          private $tags = array();               public function __construct($id,$time,$content,$postId) {         $this->uid = $id;         $this->timeStamp = $time;         $this->content = $content;         $this->postId = $postId;     }          public function setOriginPostId($postId)     {         $this->originPostId = $postId;     }          public function getPostId()     {         return $this->postId;     }          public function getTimeStamp()     {         return $this->timeStemp;     }          public function getUid()     {         return $this->uid;     }          public function getContent()     {         return $this->content;     }                public function getWebTitle()     {         return $this->webTitle;     }          public function pushPostId($postId)     {         $this->subPosts[] = $postId;     }          public function saveToDb()     {         $redisCli = new Redis(ServerConfig::$redisAddr);         $redisCli->hSet("post:$this->postId","uid",$this->uid);         $redisCli->hSet("post:$this->postId","time",$this->timeStamp);         $redisCli->hSet("post:$this->postId","content",$this->content);                  $redisCli->hSet("post:$this->postId","originPostId",$this->originPostId);                     $redisCli->set("post:$this->webTitle:$this->postId",$this->postId);                  foreach($this->tags as $tag)         {             $redisCli->sAdd("post:$this->postId:tags",$tag);         }                  foreach($this->subPosts as $postId)         {             $redisCli->lPush("post:$this->postId:subPost",$postId);         }                       }      }     每當用戶發布一個帖子的時候,他的所有的粉絲必須看得到他的帖子才可以!這裡我們有推和拉兩種方式,對於現在的新浪微博,據說是采取推和拉結合的兩個方式,我們的小系統。推:每當用戶發表一個新貼子的時候,就將他的帖子的id主動告知他所有的粉絲。拉:用戶發布一個新的帖子什麼都不要做,而當他的粉絲請求最新的內容的時候,則需要便利他所有的關注人,取得最新的帖子,然後按照時間排序取出來。推比較消耗內存,拉則是比較消耗cpu。據說新浪微博采用推和拉結合的方式,比如當一個普通用戶則是推,但是如果是一個大明星有著幾千萬粉絲的大號,當發布一個帖子的時候,則是需要他的粉絲通過拉的方式來獲取!     用戶發布一個新帖子的操作:     public function post($title,$content,$tags) {     $redisCli = new Redis(ServerConfig::$redisAddr);          $postId = postUtil::generateNewPostId();       $redisCli->Set("user:$this->uid:postTime",time());          $redisCli->lPush("user:$this->uid:news",$post->getPostId());          $followers = $redisCli->sMembers("user:$this->uid:followers");     foreach($followers as $follower )     {         $redisCli->lPush("user:$follower:news",$post->getPostId());     } }       我們將所有的帖子id推到粉絲的("user:$uid:news")中,這裡采用的是順序隊列結構體!基本也就是按照時間進行了排序(最新的帖子總是左邊)!我們不會將帖子的內容全部到放到這個字段裡,而是值存放了帖子的id,用戶請求新鮮事的時候,自己再去拉取帖子的內容!      熱門用戶/熱門帖子,Redis提供了一種有序集合類型,這樣我們利用這種有序集合類型可以做熱門,熱門用戶排行和熱門帖子排行!比如我們可以根據用戶的粉絲數量做排行,很容易得到前二十名熱門用戶,根據帖子的閱讀量做熱門帖子的排行了!      這樣一個簡單的feed系統就算是完成了!但是如果要做大,確實還是有很多系統要做!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved