`
powersoft
  • 浏览: 198821 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
53a63413-d61c-321e-8dc6-5008e88923c6
Redis官方文档翻译和源...
浏览量:191568
社区版块
存档分类
最新评论

Redis官方文档(7) ——使用Redis实现Twitter(下)

阅读更多
Redis3官方文档(7)
——使用Redis实现Twitter(下)


    把loadUserInfo作为一个单独的函数有点大题小做了,但是在复杂的程序中这是一个很好的方法。认证中唯一被遗漏的事情就是登出了。我们怎么来做登出呢?很简单,我们改变user:1000的auth字段中的随机串,从auths哈希中删除旧的认证秘钥,然后添加一个新的。
    重要:登出的步骤解释了为什么我们不是仅仅在auths哈希中查看认证秘钥以后认证用户,而是双重检查user:1000的auth字段。真正的认证字符串是后者,auths哈希只不过是一个会挥发(volatile)的认证字段,或者,如果程序中bug或者脚本被中断,我们会发现auths键中有多个对应同一个用户ID的入口。登出代码如下(logout.php):
include("retwis.php");

if (!isLoggedIn()) {
    header("Location: index.php");
    exit;
}

$r = redisLink();
$newauthsecret = getrand();
$userid = $User['id'];
$oldauthsecret = $r->hget("user:$userid","auth");

$r->hset("user:$userid","auth",$newauthsecret);
$r->hset("auths",$newauthsecret,$userid);
$r->hdel("auths",$oldauthsecret);

header("Location: index.php");

    这就是我们所描述的,你需要去理解的。

    帖子(Updates)
    更新(updates),也就是我们知道的帖子(posts),更加简单。为了创建一个新的帖子我们这么干:
INCR next_post_id => 10343
HMSET post:10343 user_id $owner_id time $time body "I'm having fun with Retwis"

    如你所见,每篇帖子由有3个字段的哈希组成。帖子拥有者的用户ID,帖子撞见时间,最后是帖子的正文,真正的状态消息。
    创建一个帖子后,我们获取其帖子ID,LPUSH其ID到帖子作者的每个粉丝用户的时间轴中,当然还有作者自己的帖子列表中(每个人事实上关注了他自己)。post.php文件展示了这一切是怎么执行的:
include("retwis.php");

if (!isLoggedIn() || !gt("status")) {
    header("Location:index.php");
    exit;
}

$r = redisLink();
$postid = $r->incr("next_post_id");
$status = str_replace("\n"," ",gt("status"));
$r->hmset("post:$postid","user_id",$User['id'],"time",time(),"body",$status);
$followers = $r->zrange("followers:".$User['id'],0,-1);
$followers[] = $User['id']; /* Add the post to our own posts too */

foreach($followers as $fid) {
    $r->lpush("posts:$fid",$postid);
}
# Push the post on the timeline, and trim the timeline to the
# newest 1000 elements.
$r->lpush("timeline",$postid);
$r->ltrim("timeline",0,1000);

header("Location: index.php");

    函数的核心是这个foreach循环。我们使用ZRANGE获取当前用户的所有粉丝,然后通过遍历LPUSH帖子到每一位粉丝的时间轴列表中。
    注意,我们也为所有的帖子维护了一个全局的时间轴,这样我们就可以在Retwis首页轻易的展示每个人的帖子。这只需要执行LPUSH到时间轴列表。回到现实,我们难道没有开始觉得在SQL中使用ORDER BY来排序按照时间顺序添加的东西有一点点奇怪吗?至少我只这么认为的。
    上面的代码有个有意思的地方值得注意:我们对全局时间轴执行完LPUSH操作之后使用了一个新命令LTRIM。这是为了裁剪列表到1000个元素。全局时间轴事实上只会用在首页展示少量帖子,没有必要获取全部历史帖子。
    基本上LTRIM+LPUSH是Redis中创建上限(capped)集合的一种方式。

    帖子分页(Paginating)
    我们如何使用LRANGE来获取一个范围的帖子,展现这些帖子在屏幕上,现在已经相当清楚了。代码很简单:
function showPost($id) {
    $r = redisLink();
    $post = $r->hgetall("post:$id");
    if (empty($post)) return false;

    $userid = $post['user_id'];
    $username = $r->hget("user:$userid","username");
    $elapsed = strElapsed($post['time']);
    $userlink = "<a class=\"username\" href=\"profile.php?u=".urlencode($username)."\">".utf8entities($username)."</a>";

    echo('<div class="post">'.$userlink.' '.utf8entities($post['body'])."<br>");
    echo('<i>posted '.$elapsed.' ago via web</i></div>');
    return true;
}

function showUserPosts($userid,$start,$count) {
    $r = redisLink();
    $key = ($userid == -1) ? "timeline" : "posts:$userid";
    $posts = $r->lrange($key,$start,$start+$count);
    $c = 0;
    foreach($posts as $p) {
        if (showPost($p)) $c++;
        if ($c == $count) break;
    }
    return count($posts) == $count+1;
}

    showPost只是转换和打印一篇HTML帖子,showUserPosts获取一个范围的帖子然后传递给showPost。
    注意:如果帖子列表很大的话,LRANGE比较低效,我们想访问列表的中间元素,因为Redis列表的背后实现是链表。如果系统设计为为几百万的项分页,那最好求助于有序集合。

    关注用户(Following users)
    我们还没有讨论如何创建关注/粉丝关系,尽管这并不困难。如果ID为1000的用户(antirez)想关注用户ID为5000的用户(pippo),我们需要同时创建关注和被关注关系。我们只需要调用ZADD:
ZADD following:1000 5000
ZADD followers:5000 1000

    仔细关注一下同一个模式。理论上,在关系型数据库中,关注者列表和粉丝列表会在同一张表中,使用像following_id和follower_id这样的列。你可以使用SQL查询来抽取每个用户的关注者和粉丝。在键值数据库中则有一些不同,因为我们需要设置1000关注5000,同时5000被1000关注的双重关系。这是要付出的代价,但是另一方面,访问数据很简单并相当的快。将这些作为独立的集合可以让我们做一些有意思的事情。例如,使用ZINTERSTORE我们可以获得两个不同用户的粉丝的交集,于是我们可以给我们的Twitter系统增加一个特性,当你访问某个人的主页时,可以很快的告诉你”你和Alice有34个共同粉丝”这样类似的事情。
    你可以在follow.php中找到设置和删除关注/粉丝关系的代码。

    水平伸缩(horizontally scalable)
    亲爱的读者,如果你意识到了这一点你就已经是一个英雄了。谢谢你。在讨论水平伸缩之前有必要查看一下单台服务器的性能。Retwis相当的快,没有任何的缓存。在一台很慢的过载的服务器上,apache的benchmark使用100个并发客户端发出10000个请求,测量出平均uv为5毫秒。这意味着单台Linux服务器每天可以服务数以百万计的用户,这个像猴子屁股一样的慢,想象一下如果用更新的硬件会是什么结果。
    然而,你不可能永远使用单台服务器,如何伸缩一个键值存储?
    Retwis不执行任何多键操作,所以伸缩很简单:你可以使用客户端分片,或者类似于Twemproxy的分片代理,或者是即将横空出世的Redis集群。
    想更多的了解这个主题请阅读我们的分片文档。这里我们想强调的是,在键值存储系统中,如果你小心设计,数据集是可以拆分到相互独立的小的键上去。相比较使用语义上更复杂的数据库系统,分布这些键到多个节点更简单直接和可预见。
===============================================================================
    大家好,我是阮威。华中科技大学,计算机软件专业硕士。毕业后加入腾讯,先后在腾讯电子商务部和无线游戏产品部工作,现供职于欢聚时代基础产品部。IT男,至今。对技术有强烈的热情,对技术以外的事物热情更高。
    我的座右铭是“呼喊移动人的移动连接,践行自由人的自由联合”。欢迎大家收听我的公众账号。
3
0
分享到:
评论
2 楼 powersoft 2015-04-18  
yanworld 写道
ZADD following:1000 5000  pippo
ZADD followers:5000 1000  antirez

关注人的地方,正确的应该是这样的吧?
是不?


不是,这里只需要id就可以了,不需要用户名。
1 楼 yanworld 2015-04-17  
ZADD following:1000 5000  pippo
ZADD followers:5000 1000  antirez

关注人的地方,正确的应该是这样的吧?
是不?

相关推荐

    Redis官方文档.zip_redis

    **Redis官方文档详解** Redis,全称Remote Dictionary Server,是一个开源的、支持网络的、键值存储系统。它通常被用作数据库、缓存和消息代理。Redis以其高性能、丰富的数据结构以及简单易用的API而闻名。此文档将...

    php-redis 中文文档

    通过使用 `phpredis`,开发者可以轻松地在 PHP 中实现缓存、队列管理以及其他内存级别的数据存储功能。 #### 二、安装与配置 - **下载地址**: `https://github.com/owlient/phpredis` - **支持版本**: 支持 Redis ...

    redis说明文档使用说明

    redis说明文档使用说明redis说明文档使用说明redis说明文档使用说明redis说明文档使用说明redis说明文档使用说明redis说明文档使用说明

    最新版redis官方中文说明文档(2016)

    Redis支持的数据类型有字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)和有序集合(Sorted Sets),这些数据结构的使用极大地丰富了应用程序的实现方式。 字符串是Redis最基础的数据类型,可以...

    Redis 中文文档

    Redis 的官方文档非常详尽,包含了从基础概念到高级特性的详细介绍。下面将根据提供的部分内容,对Redis中的关键知识点进行解析。 #### 三、键空间通知(keyspace notification) 键空间通知是Redis为客户端提供的...

    redis文档 redis api redis集群配置官方文档中文版本

    从网上抓取的redis文档,中文版本!!提供给在没有网络下的朋友查询参考使用!!

    scala连接redis哨兵模式 demo 使用scala的redis库(csdn)————程序.pdf

    因此,用户可能会被建议去使用Java的Redis客户端,这可能意味着Java的Redis客户端库有更好的文档和社区支持,更适合在哨兵模式下使用。 以上内容中,由于文件中也提到了一些OCR识别错误或漏识别的情况,因此在解析...

    redis安装使用文档

    - 下载最新版本的Redis源代码,通常从官方网站redis.io下载。 - 解压并进入源代码目录。 - 使用`make`命令编译源码。 - 执行`sudo make install`将Redis服务器安装到系统路径。 - 将Redis配置文件`redis.conf`复制到...

    Redis 中文文档.pdf

    这些事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发,因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下,直接使用键空间通知功能。 二、事务(transaction) Redis 的事务机制允许...

    redis官方文档中文版

    这份“redis官方文档中文版”提供了全面的Redis使用指南和技术详解,对于理解和掌握Redis的各项功能和最佳实践至关重要。 文档通常会从以下几个方面进行详细介绍: 1. **Redis简介**:Redis是一个开源(BSD许可)...

    redis streams官方文档和中文部分翻译

    Redis Stream本来是计划放在4.0这个大版本中发布(原计划4.2),但是由于确实是个比较重磅的feature,对内核的改动也比较大,目前已经提升到Redis 5.0发布,根据作者Twitter的消息,不出意外,18年上半年我们可以看到...

    php redis 中文API和redis chm文档

    `redis_cmd.chm`是一个帮助文件,包含了Redis命令的详细信息,而`redis中文API.docx`则可能是PHP Redis扩展的中文API文档,用于指导PHP开发者如何使用这个扩展来调用Redis的各种功能。 1. **Redis命令**: `redis_...

    Redis 中文文档-01061629.pdf

    键空间通知通过 Redis 的订阅与发布功能(pub/sub)来进行分发,因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下,直接使用键空间通知功能。 事务(Transaction) Redis的事务可以确保多个命令...

    Redis在Delphi7下使用,支持发布、订阅等

    总之,这个项目涵盖了在Delphi7环境下集成Redis服务的基本步骤,包括配置连接、创建用户界面、使用线程进行异步操作以及实现发布/订阅功能。通过理解这些文件的作用和Delphi7的编程模式,你可以构建出一个能够与...

    redis官方中文说明文档(HTML版本)

    Redis 是一个开源的、高性能...总之,这份Redis官方中文说明文档是学习Redis不可或缺的资料,无论你是初学者还是经验丰富的开发者,都能从中受益。通过阅读和实践,你将能够熟练地运用Redis来构建高效、可扩展的应用。

    flink-connector-redis-2.10-1.1.5-API文档-中文版.zip

    包含翻译后的API文档:flink-connector-redis_2.10-1.1.5-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.flink:flink-connector-redis_2.10:1.1.5; 标签:apache、flink、connector、redis、中文文档...

    promethues(普罗米修斯)监控redis-详细文档

    在本文档中,我们将详细介绍如何使用Prometheus 2.35.0监控Redis实例,以及如何配置报警机制。 首先,Prometheus 支持两种方式来添加监控目标: 1. 静态配置:这种方式需要手动在Prometheus配置文件中添加每个要...

    redis帮助文档之geo.md

    redis帮助文档之geo

    Centos7安装Redis的文档和安装包(redis单例、哨兵、集群).rar

    Centos7安装Redis的文档和安装包,包含redis单例模式、哨兵模式和集群的配置,Redis的版本是5.0.7。

Global site tag (gtag.js) - Google Analytics