zoukankan      html  css  js  c++  java
  • 实现Timeline

    Redis实现Timeline

    上回写了使用Redis实现关注关系,这次说说使用Redis实现Timeline。

     

    Timeline的实现一般有推模式、拉模式、推拉结合这几种。
    推模式:某人发布内容之后推送给所有粉丝,空间换时间,瓶颈在写入;
    拉模式:粉丝从自己的关注列表中读取内容,时间换空间,瓶颈在读取;
    推拉结合:某人发布内容后推送给活跃粉丝,不活跃粉丝则使用拉取。

     

    目前只讨论推模式,考虑单个feed内容实体存入散列(hashes)、每个用户的timeline列表存入列表(lists)。

     

    1、发布

     

    发布者发布内容后,生成唯一feedID,以feedID为key存入hashes。
    首先从发布者的粉丝表里获取所有粉丝,再进行推送。

     

    逻辑如下:

     

    // 使用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);
    }

     

    2、读取

     

    某用户登陆之后,获取timeline Lists中的值,再从Hashes取数据进行处理。

     

    $feedIDs = $redis->LRANGE("{$userID}:timeline", 0, 30); //取30条数据
    foreach ($feedIDs as $feedID) {
        $feedData = $redis->HGETALL($feedID);
        // TODO:进一步进行处理、整合等操作。
    }

     

    3、删除

     

    当发布者删除某条消息后,循环所有粉丝列表,并执行删除操作。

     

    // 从发布者自己的已发布删除掉
    $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。

     

    后记

     

    Timeline系统说起来会很复杂,也不可能只靠Redis去实现。本文只是一个大体的思路,应对小数据量基本足够。

     

    博客:http://blog.lovemydeer.com/2016/03/19/redis-timeline.html

  • 相关阅读:
    远程桌面连接win10问题解决
    为什么n各节点的的二叉链表中有n+1个空链域
    西门子Step7找不到有效授权的解决方法
    表达式树获取函数命名
    逆波兰表达式
    双向循环链表实践
    快速找到未知长度单链表的中间节点
    java的ArrayList(线性表)和LinkedList(双向链表)的深入学习
    23种设计模式中的访问者模式
    23种设计模式中的原型模式
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5377534.html
Copyright © 2011-2022 走看看