开发者社区> 石门-archy> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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系统就算是完成了!但是如果要做大,确实还是有很多系统要做!

   android客户端部分的内容,我们下篇文章见!


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
php ok3w系统开源软件,php的进销存软件jiandanjxc
以前使用过一个ok3w的系统,使用起来感觉不错,从.4.7左右,一直用到5.0到后来ok3w出了6.0了已经静态后的,就没有再用过,因为从5.0后ajax的调试就不能用netbox了,所以以后就用的少了,原来的ok3w的系统是asp的,现在看起来,有好多的新技术不能应用到这个程序上,所以打算使用php来从新写一下这程序,开源出来, 因为程序的类都放在了appcode的文件夹中,所以猜测写
1909 0
【PHP秒杀系统】第一篇 环境准备即MySQL的封装
【PHP秒杀系统】第一篇 环境准备即MySQL的封装
33 0
MacOs M1 芯片分布式搭建 Nginx+PHP+MySQL和多站点域名访问
一、安装Nginx 问题:Mac 在安装nginx之前记得把原本的apache2给卸载删除了,要不然后期会出现端口号被占用,或者有时候nginx用不了
128 0
PHP处理MySQL关联查询
什么关联查询? a)在MySQL中的Select语句中,我们经常会有复杂的业务需要使用join子语句,包括left join、right join、inner join、left outer join、right outer join、full join b)那么使用以上几种方式进行表查询的时候、对数据库的压力是很大的,怎么个大法呢,我们来测试一下: i.首先我们先搞一些数据 class表200w数据 user表 40w数据 ii.我们接下来查询15个班级下面的所有学生
68 0
PHP 和 MySQL 的合作方式
PHP 和 MySQL 的合作方式
37 0
使用PHP生成MySQL数据字典
给大家分享一个自己写的函数:使用PHP生成mysql字典。
68 0
PHP中MySQL操作
本次使用的demo是MySQL的示例数据库employees,点击下载地址,注意在导入的时候,在employees.sql文件中,将source改成你当前的目录。
38 0
centos下 Apache、php、mysql默认安装路径
centos下 Apache、php、mysql默认安装路径   http://blog.sina.com.cn/s/blog_4b8481f70100ujtp.html   apache: 如果采用RPM包安装,安装路径应在 /etc/httpd目录下 apache配置文件:/etc/httpd/conf/httpd.
831 0
+关注
石门-archy
石家庄某网络公司技术主管
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Redis 的高并发实战:抢购系统
立即下载
Redis的开发规范和常见问题
立即下载
Redis Cluster的基本原理
立即下载