【转载】Redis的一些使用场景
看了一些文章,关于Redis的使用场景,觉得挺好的。Redis肯定远远不止作为缓存而使用。Redis更像是一个实现很好的数据结构服务器,通过TCP栈协议提供服务。下面进行详细描述。
http://database.51cto.com/art/201107/276333.htm
(其实是对 http://oldblog.antirez.com/post/take-advantage-of-redis-adding-it-to-your-stack.html
以及这篇 http://highscalability.com/blog/2011/7/6/11-common-web-use-cases-solved-in-redis.html 的翻译和补充)
显示最新的项目列表
下面这个语句常用来显示最新项目,随着数据多了,查询毫无疑问会越来越慢。
SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10
在Web应用中,“列出最新的回复”之类的查询非常普遍。
因为项目本来就是按这个顺序被创建的,但要输出这个顺序却不得不进行排序操作。
类似的问题就可以用Redis来解决。比如说,我们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论。
- 我们假设数据库中的每条评论都有一个唯一的递增的ID字段。
- -每次新评论发表时,我们会将它的ID添加到一个Redis列表:
- LPUSH latest.comments <ID>
- -我们将列表裁剪为指定长度,因此Redis只需要保存最新的5000条评论:
- LTRIM latest.comments
- FUNCTION get_latest_comments(start,num_items):
- id_list = redis.lrange('latest.comments',start,start+num_items-)
- IF id_list.length < num_items
- id_list = SQL_DB('SELECT ... ORDER BY time LIMIT ...';)
- END
- RETURN id_list
- END
SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。
删除与过滤
我们可以使用LREM来删除评论。
可以给列表使用过滤器来处理(过滤器/scan查看这篇文章 link )。也可以针对每种不同情况使用不同的列表。因为Redis处理速度很快。
排行榜相关
在按得分排序以及实时更新这些几乎每秒钟都需要更新的功能上数据库的性能不够理想。
- 典型的比如那些在线游戏的排行榜,比如一个Facebook的游戏,根据得分你通常想要:
- -列出前100名高分选手
- -列出某用户当前的全球排名
- 这些操作对于Redis来说小菜一碟,即使你有几百万个用户,每分钟都会有几百万个新的得分。
模式是这样的,每次获得新得分时,我们用这样的代码:
- ZADD leaderboard <score> <username>
- 得到前100名高分用户很简单:ZREVRANGE leaderboard 。
- 用户的全球排名也相似,只需要:ZRANK leaderboard <username>。
- 以上的username 也可以用userid 来替换以更具扩展性。
按照用户投票和时间排序
排行榜的一种常见变体模式就像Reddit或Hacker News用的那样,新闻按照类似下面的公式根据得分来排序:
- score = points / time^alpha
这种模式很有趣。因此用户的投票会相应的把新闻挖出来,但时间会按照一定的指数将新闻埋下去。下面是我们的模式,当然算法由你决定。
- 模式是这样的,开始时先观察那些可能是最新的项目,例如首页上的1000条新闻都是候选者,因此我们先忽视掉其他的,这实现起来很简单。
- - 每次新的新闻贴上来后,我们将ID添加到列表中,使用LPUSH + LTRIM,确保只取出最新的1000条项目。
- - 有一项后台任务获取这个列表,并且持续的计算这1000条新闻中每条新闻的最终得分。计算结果由ZADD命令按照新的顺序填充生成列表,老新闻则被清除。
- 这里的关键思路是排序工作是由后台任务来完成的。
过期项目处理
另一种常用的项目排序是按照时间排序。我们使用unix时间作为得分即可。模式如下:
- - 每次有新项目添加到我们的非Redis数据库时,我们把它加入到排序集合中。这时我们用的是时间属性,current_time和time_to_live。
- - 另一项后台任务使用ZRANGE…SCORES查询排序集合,取出最新的10个项目。如果发现unix时间已经过期,则在数据库中删除条目。
计数
有了原子递增(atomic increment),你可以放心的加上各种计数,用GETSET重置,或者是让它们过期。
- INCR user:<id>
- EXPIRE user:<id>
- 或者
- GETSET user:<id>
这样当60秒内用户访问密集到达多少次数之后,就会触发一定的事件,比如blocking,或者弹窗提醒等。
特定时间内的特定项目
另一项对于其他数据库很难,但Redis做起来却轻而易举的事就是统计在某段特点时间里有多少特定用户访问了某个特定资源。
比如我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章。
- 每次我获得一次新的页面浏览时我只需要这样做:
- SADD page:day1:<page_id> <user_id>
- 当然你可能想用unix时间替换day1,比如time()-time()%(*)等等。
- 想知道特定用户的数量吗?只需要使用SCARD page:day1:<page_id>。
- 需要测试某个特定用户是否访问了这个页面?SISMEMBER page:day1:<page_id>。
实时分析正在发生的情况,用于数据统计与防止垃圾邮件等
上面提到的Redis原语比如 zrange 等很适合做实时分析。当然也可以与其他系统比如 Flume、Storm 进行结合。有时间可以看看下面这篇文章:
http://blog.csdn.net/ymh198816/article/details/51998085 《Flume+Kafka+Storm+Redis实时分析系统基本架构》
Pub/Sub
Redis其实也支持MQ操作。
运行稳定并且快速。支持模式匹配,能够实时订阅与取消频道。using commands likeSUBSCRIBE, UNSUBSCRIBE, and PUBLISH.
队列
已经注意到像list push和list pop这样的Redis命令能够很方便的执行队列操作了。
但能做的可不止这些:比如Redis还有list pop的变体命令(blpop, blocking queue),能够在列表为空时阻塞队列。
Can also do interesting things implement a rotating queue of RSS feeds to update.
缓存
让你的缓存从只能存储数据变得能够更新数据,因此你不再需要每次都重新生成数据了。
总结
目标是让你的系统变得不再复杂,让你的网站反应更快。
你不需要改变现有的数据库结构,使用Redis给你的框架带来新的东西,来完成那些从前认为不可能做到/很难做到的,或是成本太高的任务。
【转载】Redis的一些使用场景的更多相关文章
- redis数据类型及使用场景
Redis数据类型 String: Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字. 常用命令: set,get,decr,incr,mge ...
- Redis数据结构以及应用场景
1. Redis数据结构以及应用场景 1.1. Memcache VS Redis 1.1.1. 选Memcache理由 系统业务以KV的缓存为主,数据量.并发业务量大,memcache较为合适 me ...
- redis各种数据结构使用场景
一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 ...
- Redis数据结构和使用场景,redis内存淘汰策略
什么样的数据适合放入Redis? sql执行耗时特别久,且结果不频繁变动的数据,适合放入Redis. Redis是单线程的,为什么会这么快? 纯内存操作 单线程操作,避免频繁的上下文切换 采用了非阻塞 ...
- [转载] Redis资料汇总专题
转载自http://www.cnblogs.com/tommyli/archive/2011/12/14/2287614.html 1.Redis是什么? 十五分钟介绍 Redis数据结构 Redis ...
- [转载] Redis之七种武器
转载自http://blog.nosqlfan.com/html/2942.html?ref=rediszt 长生剑.孔雀翎.碧玉刀.多情环.离别钩.霸王枪.拳头是古龙笔下的七种武器,而本文打算将Re ...
- [转载] Redis实现分布式锁
转载自http://zhidao.baidu.com/link?url=m56mmWYwRgCymsaLZ2tx-GWDy5FYmUWGovEtuApjTpktHS3bhofrCS-QVGiLoWeS ...
- Redis各类型应用场景
Redis的六种特性 l ,重要消息的,然后工作线程可以选择按 ret = r.zincrby("login:login_times", 1, uid) //那么如何获得登录次数最 ...
- Redis数据库的使用场景介绍(避免误用Redis)
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/122.html?1455854235 Redis 是目前 NoSQL 领域 ...
随机推荐
- 将apk安装包安装在Android真机或者模拟器
例子如下: 一.准备 打开MAC PC上的Android模拟器方法:打开eclipse-—>window->Android Virtual Device Manager 如果是安装在真机上 ...
- HDOJ 1518 Square
Square Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- 云计算中iaas、paas、saas的区别和联系
概念: iass : Infrastructure(基础设施)-as-a-Service, paas : Platform(平台)-as-a-Service, saas : Software(软件)- ...
- 定时每天执行前一天的数据导入oracle
#!/bin/bash export LANG="en_US.UTF-8" #设定时间变量,为前一天时间 log_date=`date +%Y-%m-%d -d "-1 ...
- 关于解压覆盖IIS文件后,新的文件不具备权限导致DMS系统无法正常运行
向DMS的服务器端站点bin目录覆盖任何补丁文件,请注意:Web站点的bin目录中的文件,IIS的服务进程(Windows2003以上,都是对应Network Services账户)必须对这些文件具 ...
- 浅说Java中的反射机制(一)
在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...
- 【Apache运维基础(5)】Apache的Rewrite攻略(2)
简述 .htaccess文件(或者"分布式配置文件")提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录.作 ...
- Hadoop基础教程之重新认识Hadoop
之前,我们把hadoop从下载包部署到编写了helloworld,看到了结果.现是得开始稍微更深入地了解hadoop了. Hadoop包含了两大功能DFS和MapReduce, DFS可以理解为一 ...
- ThreadLocal的几种误区
最近由于需要用到ThreadLocal,在网上搜索了一些相关资料,发现对ThreadLocal经常会有下面几种误解 一.ThreadLocal是java线程的一个实现 ThreadLoca ...
- iOS:UIView的block函数实现转场动画---单视图
使用UIView动画函数实现转场动画——单视图 + (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration ...