博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php + Redis 写的类似于新浪微博的feed系统
阅读量:5821 次
发布时间:2019-06-18

本文共 4536 字,大约阅读时间需要 15 分钟。

       最近接了一个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);        }                    }    }
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客户端部分的内容,我们下篇文章见!

      

    

 

转载于:https://www.cnblogs.com/archy_yu/p/4311170.html

你可能感兴趣的文章
CentOS 7 装vim遇到的问题和解决方法
查看>>
JavaScript基础教程1-20160612
查看>>
FCN图像分割
查看>>
ios xmpp demo
查看>>
python matplotlib 中文显示参数设置
查看>>
【ros】Create a ROS package:package dependencies报错
查看>>
通过容器编排和服务网格来改进Java微服务的可测性
查看>>
re:Invent解读:没想到你是这样的AWS
查看>>
PyTips 0x02 - Python 中的函数式编程
查看>>
阿里云安全肖力:安全基础建设是企业数字化转型的基石 ...
查看>>
使用《Deep Image Prior》来做图像复原
查看>>
Linux基础命令---rmdir
查看>>
Android图片添加水印图片并把图片保存到文件存储
查看>>
BigDecimal 舍入模式(Rounding mode)介绍
查看>>
开源 免费 java CMS - FreeCMS1.2-标签 infoSign
查看>>
开源 免费 java CMS - FreeCMS1.9 移动APP生成栏目列表数据
查看>>
Java IO流详尽解析
查看>>
Linux VSFTP服务器
查看>>
DHCP中继数据包互联网周游记
查看>>
Squid 反向代理服务器配置
查看>>