Redis在很多方面与其他数据库解决方案不同:它使用内存提供主存储支持,而仅使用硬盘做持久性的存储;它的数据模型非常独特,用的是单线程。另一个大区别在于,你可以在开发环境中使用Redis的功能,但却不需要转到Redis。

转向Redis当然也是可取的,许多开发者从一开始就把Redis作为首选数据库;但设想如果你的开发环境已经搭建好,应用已经在上面运行了,那么更换数据库框架显然不那么容易。另外在一些需要大容量数据集的应用,Redis也并不适合,因为它的数据集不会超过系统可用的内存。所以如果你有大数据应用,而且主要是读取访问模式,那么Redis并不是正确的选择。

然而我喜欢Redis的一点就是你可以把它融入到你的系统中来,这就能够解决很多问题,比如那些你现有的数据库处理起来感到缓慢的任务。这些你就可以通过Redis来进行优化,或者为应用创建些新的功能。在本文中,我就想探讨一些怎样将Redis加入到现有的环境中,并利用它的原语命令等功能来解决传统环境中碰到的一些常见问题。在这些例子中,Redis都不是作为首选数据库。

显示最新的项目列表

下面这个语句常用来显示最新项目,随着数据多了,查询毫无疑问会越来越慢。

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

在Web应用中,“列出最新的回复”之类的查询非常普遍,这通常会带来可扩展性问题。这令人沮丧,因为项目本来就是按这个顺序被创建的,但要输出这个顺序却不得不进行排序操作。

类似的问题就可以用Redis来解决。比如说,我们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论。

我们假设数据库中的每条评论都有一个唯一的递增的ID字段。

我们可以使用分页来制作主页和评论页,使用Redis的模板:

-每次新评论发表时,我们会将它的ID添加到一个Redis列表:

LPUSH latest.comments <ID> 

-我们将列表裁剪为指定长度,因此Redis只需要保存最新的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中我们的最新ID使用了常驻缓存,这是一直更新的。但是我们做了限制不能超过5000个ID,因此我们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才需要去访问数据库。

我们的系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。

删除与过滤

我们可以使用LREM来删除评论。如果删除操作非常少,另一个选择是直接跳过评论条目的入口,报告说该评论已经不存在。

有些时候你想要给不同的列表附加上不同的过滤器。如果过滤器的数量受到限制,你可以简单的为每个不同的过滤器使用不同的Redis列表。毕竟每个列表只有5000条项目,但Redis却能够使用非常少的内存来处理几百万条项目。

排行榜相关

另一个很普遍的需求是各种数据库的数据并非存储在内存中,因此在按得分排序以及实时更新这些几乎每秒钟都需要更新的功能上数据库的性能不够理想。

典型的比如那些在线游戏的排行榜,比如一个Facebook的游戏,根据得分你通常想要:

-列出前100名高分选手

-列出某用户当前的全球排名

这些操作对于Redis来说小菜一碟,即使你有几百万个用户,每分钟都会有几百万个新的得分。

模式是这样的,每次获得新得分时,我们用这样的代码:

ZADD leaderboard  

你可能用userID来取代username,这取决于你是怎么设计的。

得到前100名高分用户很简单:ZREVRANGE leaderboard 0 99。

用户的全球排名也相似,只需要:ZRANK leaderboard 。

按照用户投票和时间排序

排行榜的一种常见变体模式就像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时间已经过期,则在数据库中删除条目。

计数

Redis是一个很好的计数器,这要感谢INCRBY和其他相似命令。

我相信你曾许多次想要给数据库加上新的计数器,用来获取统计或显示新信息,但是最后却由于写入敏感而不得不放弃它们。

好了,现在使用Redis就不需要再担心了。有了原子递增(atomic increment),你可以放心的加上各种计数,用GETSET重置,或者是让它们过期。

例如这样操作:

INCR user: EXPIRE user: 60

你可以计算出最近用户在页面间停顿不超过60秒的页面浏览量,当计数达到比如20时,就可以显示出某些条幅提示,或是其它你想显示的东西。

特定时间内的特定项目

另一项对于其他数据库很难,但Redis做起来却轻而易举的事就是统计在某段特点时间里有多少特定用户访问了某个特定资源。比如我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章。

每次我获得一次新的页面浏览时我只需要这样做:

SADD page:day1:<page_id> <user_id>

当然你可能想用unix时间替换day1,比如time()-(time()%3600*24)等等。

想知道特定用户的数量吗?只需要使用SCARD page:day1:<page_id>。

需要测试某个特定用户是否访问了这个页面?SISMEMBER page:day1:<page_id>。

实时分析正在发生的情况,用于数据统计与防止垃圾邮件等

我们只做了几个例子,但如果你研究Redis的命令集,并且组合一下,就能获得大量的实时分析方法,有效而且非常省力。使用Redis原语命令,更容易实施垃圾邮件过滤系统或其他实时跟踪系统。

Pub/Sub

Redis的Pub/Sub非常非常简单,运行稳定并且快速。支持模式匹配,能够实时订阅与取消频道。

队列

你应该已经注意到像list push和list pop这样的Redis命令能够很方便的执行队列操作了,但能做的可不止这些:比如Redis还有list pop的变体命令,能够在列表为空时阻塞队列。

缓存

Redis的缓存部分值得写一篇新文章,我这里只是简单的说一下。Redis能够替代memcached,让你的缓存从只能存储数据变得能够更新数据,因此你不再需要每次都重新生成数据了。

Redis可以解决你的问题!

现在你就可以用上Redis,让用户感到更轻松,让你的系统变得不再复杂,让你的网站反应更快。你不需要改变现有的数据库结构,使用Redis给你的框架带来新的东西,来完成那些从前认为不可能做到/很难做到的,或是成本太高的任务。

原文:http://oldblog.antirez.com/post/take-advantage-of-redis-adding-it-to-your-stack.html

让Redis在你的系统中发挥更大作用相关推荐

  1. 让Redis在你的系统中发挥更大作用的几点建议

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/105.html?1455868313 Redis在很多方面与其他数据库解决 ...

  2. 几点建议,让Redis在你的系统中发挥更大作用

    原文地址:http://antirez.com/post/take-advantage-of-redis-adding-it-to-your-stack.html Redis在很多方面与其他数据库解决 ...

  3. 物联网生物识别技术在工作场所中发挥更大作用

    组织可以使用生物识别技术通过传感器和监视来提高工作场所的安全性和员工安全性,但雇主还必须评估其潜在影响. 随着健康和安全问题成为每个企业未来的核心,人们将发现一个新的数字接口:他们的身体. 生物识别交 ...

  4. OA系统有哪些功能?在企业中发挥怎样的作用?

    OA系统是什么?为什么企业要引进OA系统?OA系统的主要功能和作用又有哪些? 一.OA系统是什么 首先,OA是office automation的简写,也就是办公自动化的意思,面向组织的日常运作和管理 ...

  5. 【物流重力货架】先进先出的重力式托盘货架(Gravity Flow Rack)在仓储中发挥着哪些作用?

    重力式货架是仓储货架中的一种,通常又被称为自重力货架,它属于重型货架,是由托盘式货架演变而来的,由多组上下纵横并列的带坡度的无动力滚筒滑道组成.存货时托盘从斜坡高端送入滑道,通过导向轮下滑,逐个存放, ...

  6. 漫谈 ClickHouse 在实时分析系统中的定位与作用

    ClickHouse 是一款由俄罗斯Yandex公司开源的OLAP数据库,拥有着卓越的性能表现,在官方公布的基准测试中,ClickHouse的平均响应速度是Vertica的2.63倍.InfiniDB ...

  7. 机器视觉系统中相机镜头选型技巧_工业相机在机器视觉系统中的地位和作用

    一.什么是工业相机 工业相机是机器视觉系统中的一个关键组件,其最本质的功能就是将光信号转变成有序的电信号.选择合适的相机也是机器视觉系统设计中的重要环节,相机的选择不仅直接决定所采集到的图像分辨率.图 ...

  8. linux如何找大文件夹,Linux系统中如何查找大文件或目录文件夹的方法

    Linux系统中如何查找大文件或文件夹的方法 在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在Linux系统中,如何去搜索一些比较大的文件呢?下面我整 ...

  9. Linux系统中如何查找大文件或目录文件夹的方法

    Linux系统中如何查找大文件或文件夹的方法 在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在Linux系统中,如何去搜索一些比较大的文件呢?下面我整 ...

最新文章

  1. 2018-4-17论文《狼群算法的研究与应用》笔记2 :高维复杂单目标连续优化问题的改进狼群算法
  2. pgpool-II中间件
  3. Python中的生成器与yield
  4. acrgis api for javaScript中的portal查询
  5. mysql strtok_c函数: strtok 和 strtok_r 详解
  6. 牛客网-《剑指offer》-跳台阶
  7. 自己手写一个Spring MVC框架
  8. [LeetCode]Patching Array
  9. 小甲鱼 python11讲作业
  10. 主机DIY玩家的必备工具包
  11. Windows问题记录之任务栏图标透明
  12. php写超级简单的登陆注册页面(适用期末作业至少要求带有数据库的)
  13. 学习TypeScrip2(任意类型)
  14. pycharm debug 提示 Python Debugger Extension Available Cython extension speeds up Python debugging
  15. 编译Nginx服务部署静态网站
  16. 用番茄工作法提升工作效率 (四)ToDoList的持续优化
  17. 计算时区函数gmt2local(time_t t)
  18. 洞态IAST自动检测S2-001漏洞
  19. 【转】一个清华学生留学香港后对人生的思考
  20. zabbix 安装 mysql_基于MySQL的zabbix安装及配置

热门文章

  1. ubuntu12.0.4不能正常关机和重启的解决方法
  2. 技术以外的功夫 ----作者:李天平
  3. Tomcat关闭后,重新启动,session中保存的对象为什么还存在解决方法
  4. 玩转Nodejs的集群
  5. javascript—事件冒泡
  6. linux下如何安装rzsz
  7. php中单引号和双引号的区别,哪个速度更快?为什么?
  8. Linux内核源代码分析-第三章 内核体系结构概述-3
  9. 【166期推荐】医院中电脑耗材采购该不该归信息科负责?
  10. 微信小程序惩治“老赖” 河北高院“老赖地图”上线