设为首页 收藏本站
查看: 897|回复: 0

[经验分享] php + Redis 写的类似于新浪微博的feed系统

[复制链接]

尚未签到

发表于 2015-7-20 08:42:23 | 显示全部楼层 |阅读模式
  最近接了一个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结构:


DSC0000.gif DSC0001.gif


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);
}

}
}
View Code  每当用户发布一个帖子的时候,他的所有的粉丝必须看得到他的帖子才可以!这里我们有推和拉两种方式,对于现在的新浪微博,据说是采取推和拉结合的两个方式,我们的小系统。推:每当用户发表一个新贴子的时候,就将他的帖子的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系统就算是完成了!但是如果要做大,确实还是有很多系统要做!
     android客户端部分的内容,我们下篇文章见!

  
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-88402-1-1.html 上篇帖子: Redis学习笔记(2) string 类型值存取 下篇帖子: tomcat8 redis session
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表