redis越来越受大家欢迎,提升下速度,做下缓存,完成KPI之利器呀。翻译一篇文章<<How to take advantage of Redis just adding it to your stack>>,来介绍下Redis的适用场景。

展现最新数据

Web应用常常要展现最新数据,就会根据时间对数据排序:

SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10

随着数据的增加,问题变得越来越复杂,速度也越来越慢。这种情况可以用Redis解决,如这个问题:一个web应用需要展示最新的20条用户评论。

  • 每当一条新评论产生时,将评论id加到redis的list中:LPUSH latest.comments <ID>
  • 裁剪list,保持固定长度(如只保留5000条):LTRIM latest.comments 0 5000
  • 当需要展示具体评论时,可以调用如下函数:
FUNCTION get_latest_comments(start,num_items):
id_list = redis.lrange("latest.comments",start,start+num_items-1)
IF id_list.length < num_items
id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
END
RETURN id_list
END

在这里,redis做为一个实时缓存,无需不停的刷新。mysql只有在需要更细节的信息和间隔可以较长的情况下被使用。

删除和筛选

注意到可以用LREM删除评论。如果删除不频繁,也可以在redis中保留这条记录,在我们去mysql查询时,会获取不到结果。

很多时候,你想筛选展现不同的数据表,使用多个redis list就可以了。每个list包含5000条,而redis用很少的内存就可以存储上百万的记录。

排行榜和相关问题

如果数据存储在DB中,且每秒都有很多更新。要想实时的展现一个分数排名榜,且要很好的性能,就会变得很困难。这个经典例子就是在线游戏的排名榜,如Facebook游戏,但是这种类型适用于很多场景。在线游戏里,你会收到非常多的用户分数更新,利用这些分数,你想完成如下功能:

  • 展现排名前100的分数
  • 展现用户自己的排名

即使你有数百万用户,每分钟有数百万的分数更新,使用Redis的sorted set处理这类问题也很容易。

处理方法:每当收到一个新分数时,就如下操作

ZADD leaderboard <score> <username>

得到前100用户排名只需:ZREVRANGE leaderboard 0 99

告诉用户自己的排名:ZREVRANK leaderboard <username>

补:ZRANK/ZRANGE是从小到大排序,ZREVRANK/ZREVRANGE是从大到小排序

你可以做的还有很多,如展示和用户排名相近的分数:ZRANGEBYSCORE leaderboard 500 700

根据用户投票和时间排序

上个例子是根据分数排名,但是新闻网站会采用下面的公式排名新闻。

score = points / time^alpha

用户投票会相应的提升排名,但是时间会指数式的拉低排名。可以发现可以展现在首页的新闻只可能在最新的新闻中选出(如最新的1000条),所以可以忽略其他的新闻:

  • 每当提交一条新闻时,将ID增加到list中:LPUSH + LTRIM(保证1000条)
  • 启动一个线程不断的读取list并计算最终的分数,然后使用zadd将结果存到sorted set中,同时将旧新闻从sorted set中清除

在这个例子中,我们使用了保存1000条新闻、根据分数排名的sorted set。这个sorted set可以支持每秒10万次的查询,很容易的适应网站的规模

数据过期

sorted set的另一个用处可以用时间来索引数据,如unix time做为score。但是更好的使用我们可以用来过期主库中的一些数据:

  • 当有新数据插入DB时,将它同时插入sorted set,用该数据应该过期的时间做为score(current_time + time_to_live)
  • 后台程序使用ZRANGE ... WITHSCORES来去最新的10条,如果表示时间的score已经过去了,我们就将这条数据从db中删除

计数

使用INCRBY和其他类似的命令,Redis可以成为一个很好的计数器。很多时候,你想在db中新增计数器来统计新信息,但又不得不避免使用它,因为对于db来说它是个写密集的任务。

使用Redis就没有这种顾忌了。原子自增实现计数,GETSET原子性的获得计数器当前值并清零,设置有效期来达到只在规定时间内进行计数的目的。

INCR user:<id>
EXPIRE user:<id> 60

如上,你可以计数用户60s内看了多少网页,如果达到20,你可以展现一些提示或者横幅。

固定时间内单独的N条数据

统计一段时间内浏览某资源的单独用户量,这个功能对于db很困难,但使用redis就很容易实现。例如,我想知道阅读一篇文章的单独注册用户数或者单独IP数。

每当获得一次页面浏览时,只需要做:

SADD page:day1:<page_id> <user_id>

day1可以用今天的第一秒(unix time: time() - (time()%3600*24))。

想知道单独用户数?SCARD page:day1:<page_id>

想知道某个用户是否已经看过该页面?SISMEMBER page:day1:<page_id>

实时分析

通过redis的各种命令和数据结构,可以很容易的实现大数据的实时统计,来增强反垃圾邮件系统或者用新信息来提高服务质量。

Pub/Sub

Redis的Pub/Sub非常简单、稳定、快速,而且支持模式匹配、动态订阅/取消订阅频道等等。可参考http://redis.io/topics/pubsub

队列

你可能已经注意到list的push/pop命令很适合用来实现队列,当list没有元素时,你甚至可以使用BLPOP来阻塞POP命令。

Redis做为队列的使用可以参考Resque,这个库由Github的哥们实现和推广。

list的RPOPLPUSH,sorted set等都可以实现很多有趣的队列。

缓存

单单这部分就可以用一篇专门的博客来介绍。这里长话短说,Redis可以做为memcached的替代,让你的cache更新更容易,数据管理更方便。

Redis现在就可以修复你的问题

现在就使用redis吧,会让你的用户更满意,系统更简单,网址响应更快。不需要使用redis来替换已有的组件,用redis去解决更加不可能、更加困难、更有价值的事吧。

Have fun!

终于意译完了,这哥们看来很喜欢redis。redis确实提供了各种命令和足够的数据结构,来完成各种复杂的、不可思议的工作。想要用的好,就去更多的了解吧。redis命令参考

redis系列-redis的使用场景的更多相关文章

  1. redis系列-redis的持久化

    redis对数据的持久化有两种方式:RDB(快照保存)和AOF(命令日志). RDB 介绍:将内存快照保存到磁盘,dump.rdb二进制文件 触发:满足“N 秒内数据集至少有 M 个改动”,或使用sa ...

  2. redis系列-redis的连接

    Redis 是完全开源免费的,遵守BSD协议,先进的key - value持久化产品.它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list ...

  3. Redis系列---redis简介01

    一. 本章我们将用简短的几句话来帮助你快速的了解什么是redis,初学者不必深究 1 Redis简介 Remote Dictionary Server(Redis)是一个开源的使用ANSI C语言编写 ...

  4. Redis 系列

    Redis 系列 [Redis 系列(01)安装配制] [Redis 系列(02)数据结构] [Redis 系列(03-1)进阶 - 发布订阅] [Redis 系列(03-2)进阶 - 事务] [Re ...

  5. 国内外三个不同领域巨头分享的Redis实战经验及使用场景

    Redis不是比较成熟的memcache或者Mysql的替代品,是对于大型互联网类应用在架构上很好的补充.现在有越来越多的应用也在纷纷基于Redis做架构的改造.首先简单公布一下Redis平台实际情况 ...

  6. (转)国内外三个不同领域巨头分享的Redis实战经验及使用场景

    随着应用对高性能需求的增加,NoSQL逐渐在各大名企的系统架构中生根发芽.这里我们将为大家分享社交巨头新浪微博.传媒巨头Viacom及图片分享领域佼佼者Pinterest带来的Redis实践,首先我们 ...

  7. Redis系列整理

    0.Redis系列-安装部署维护篇 1.Redis系列-远程连接redis并给redis加锁 2.Redis系列-存储篇string主要操作函数小结 3.Redis系列-存储篇list主要操作函数小结 ...

  8. Redis实战经验及使用场景

    随着应用对高性能需求的增加,NoSQL逐渐在各大名企的系统架构中生根发芽.这里我们将为大家分享社交巨头新浪微博.传媒巨头Viacom及图片分享领域佼佼者Pinterest带来的Redis实践,首先我们 ...

  9. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

随机推荐

  1. asp.net C# cookies 的使用方法

    Response.Cookie("username").value="aa" 写入username=Request.Cookies("username ...

  2. Winform中Grid跨行复制一列

    Private Sub DataCopyToGrid() '判断剪切板中是否存在内容 If Clipboard.ContainsText Then Dim str = Clipboard.GetTex ...

  3. js动态时间

    一.在<head></head> 之间写入下面js代码 <script type="text/javascript" language="J ...

  4. JSTL和EL表达式多重if问题

    俾人以前在写一个查询功能时,由于结果状态分好几种,于是页面就用<c:if></c:if>写了一大堆来判断,后来上网查了下资料,发现有个语法类似于多重if,挺方便的,语法是 &l ...

  5. C语言教学--二维数组和指针的理解

    对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻. 我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, ...

  6. 关于Java深clone 的例子学习

    之前http://www.cnblogs.com/lhppom/p/4857702.html里有提到关于Java的深克隆的学习,深浅区别就是在于仅复制对象引用和复制对象引用所指向的对象,最近在看< ...

  7. Struts2之提交对象数组至后台

    struts2中有许多很好的特性,比如在设置好getter和setter方法后,加上前端的匹配设置,后台即可自动将前端输入的数据转换为后台的相应的对象. 如现在传入一个Person类的对象,其中Per ...

  8. 【CronExpression表达式详解和案例】

    1. cron表达式格式: {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)} 2. cron表达式各占位符解释: {秒数} ==> 允许值范围: 0~59 ,不允许 ...

  9. Spring学习笔记 6. 尚硅谷_佟刚_Spring_Bean 之间的关系

    1,继承关系 首先从简单的代码来看,有一个Address类,配置文件有两个bean (1)Address类 package com.zsq; public class Address { privat ...

  10. 有一种感动叫ACM(记陈立杰在成都赛区开幕式上的讲话)

    各位选手,各位教练,大家好,我是来自清华大学交叉信息学院的陈立杰,今天很荣幸站在这里代表全体参赛选手发言.对于我来说,这是我第一次正式参加ACM的比赛.不过我跟ACM之间的缘分,大概在很早的时候就已经 ...