`
zhaomengsen
  • 浏览: 209328 次
  • 性别: Icon_minigender_1
  • 来自: 河北
社区版块
存档分类
最新评论

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

阅读更多
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/105.html?1455868313
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 <score> <username>
你可能用userID来取代username,这取决于你是怎么设计的。
得到前100名高分用户很简单:ZREVRANGE leaderboard 0 99。
用户的全球排名也相似,只需要:ZRANK leaderboard <username>。
按照用户投票和时间排序
排行榜的一种常见变体模式就像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:<id> EXPIRE
    user:<id> 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给你的框架带来新的东西,来完成那些从前认为不可能做到/很难做到的,或是成本太高的任务。
分享到:
评论

相关推荐

    100讲带你实战基于Redis的高并发预约抢购系统.zip

    Redis,作为一款高性能的键值存储系统,因其内存存储、快速响应、丰富的数据结构以及强大的持久化能力,在高并发场景下得到了广泛应用,尤其在预约抢购系统中发挥着关键作用。本系列教程将深入探讨如何利用Redis构建...

    redis-desktop-manager

    在"redis-desktop-manager"中,我们可以看到以下几个主要功能和知识点: 1. **连接管理**:Redis Desktop Manager允许用户创建和管理多个Redis服务器的连接,包括设置主机名、端口号、密码、数据库编号等信息。这...

    redis4.0.11-16离线安装包适应于麒麟V10SP1

    4.0.11是Redis的一个稳定版本,带来了诸多增强和改进,包括但不限于以下几点: 1. **新功能**:Redis 4.0引入了流(Streams)数据结构,这是类似于日志的多路复用数据模型,支持复杂的查询和数据处理。这使得Redis...

    Redis3.2的windows版本

    在Redis 3.2中,引入了多个新特性和优化,包括但不限于以下几点: 1. **集合类型**(Sets)和**有序集合**(Sorted Sets)的性能提升:Redis 3.2对集合操作进行了优化,尤其是`SADD`, `SREM`, `SMEMBERS`等命令的...

    Redis7 windows版

    4. 如果你想让Redis在系统启动时自动运行,可以使用`redis-server --service-install`命令来安装Redis为Windows服务。这将允许你在服务管理器中管理和控制Redis。 5. 安装服务后,使用`redis-server --service-start...

    redis4.0.8

    如果需要更大规模的扩展,可以搭建Redis Cluster集群。 关于提供的`安装教程.pdf`,它应该包含更详细的步骤、最佳实践和可能遇到的问题及解决方案。阅读这份文档,可以更深入地了解如何在特定操作系统上安装和配置...

    redis-5.0.5-bin.zip

    3. 支持持久化:Redis可以通过RDB(快照)或AOF(日志)两种方式实现数据持久化,确保在系统崩溃后能恢复数据。 4. 主从复制:通过复制机制,可以创建多个从节点,提高数据可用性和服务扩展性。 5. 事务支持:Redis...

    redis,版本是5.0.4

    在这个版本中,我们主要会探讨以下几个关键知识点: 1. **Redis的数据类型**:Redis支持五种基本数据类型,包括字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)和有序集合(Sorted Sets)。这些数据类型为...

    Redis-x64-4.0.2.2.msi

    在使用Redis-x64-4.0.2.2.msi进行安装时,需要注意以下几点: 1. **系统需求**:确保你的计算机是64位操作系统,因为这是64位版本的Redis。 2. **安装过程**:遵循MSI安装向导的步骤,选择合适的安装路径和配置选项...

    redis测试代码

    Redis是一款高性能的键值对数据库,常用于缓存和数据持久化。在本文中,我们将深入探讨Redis的基础知识,测试代码...通过对这些测试代码的学习和实践,开发者可以更好地理解和使用Redis,从而在项目中发挥其最大潜力。

    redis缓存技术

    Redis,全称Remote Dictionary Server,是一款高性能的键值对存储系统,常被用作数据库、缓存和消息中间件。Redis以其速度快、数据结构丰富、...这份资料将帮助你深入了解Redis的各个方面,并在实际项目中发挥其优势。

    Redis实战与入门指南

    Redis,全称Remote Dictionary Server,是一款高性能的键值对存储系统,常被用作数据库、缓存和消息中间件。...通过阅读和实践,你可以更好地理解Redis如何在大数据场景下发挥其优势,提升系统性能。

    Redis大数据之路-dtcc-唐福林

    - **Redis的优势**:作为一款内存数据库,Redis以其高性能、丰富的数据结构以及灵活的持久化机制等特点,在大数据处理中发挥了重要作用。 - **内存成本考量**:虽然Redis提供了极高的性能,但在实际应用中也需要考虑...

    基于SpringBoot、Redis、RabbitMQ、MySQL的商城秒杀项目源码.zip

    在秒杀场景中,Redis发挥了重要作用,由于其高速读写性能,可以用来存储秒杀商品信息,快速响应用户的请求。同时,Redis的队列功能可以用于处理秒杀请求,避免并发问题。 3. **RabbitMQ**: RabbitMQ是一个开源的...

    php_redis-5.3-vc9

    《PHP与Redis扩展:php_redis-5.3-vc9深度解析》 在Web开发领域,PHP作为一种广泛使用的服务器端脚本语言,以其简洁...同时,理解并掌握Redis的各种数据结构及其操作,将有助于在实际项目中发挥出Redis的强大功能。

    nicolasff-phpredis-2.2.1-3-g950765e.tar.gz

    在部署和使用PHPRedis时,需要注意以下几点: 1. 首先,确保服务器上已经安装了Redis服务器,并且正确配置和运行。 2. 下载并编译PHPRedis源代码,将其添加到PHP的扩展目录中。 3. 修改php.ini文件,添加对PHPRedis...

    redis-3.0.2.tar.gz

    了解以上知识点后,你可以对 Redis-3.0.2 进行安装、配置、使用和维护,充分发挥其在缓存、实时数据处理和分布式应用中的潜力。在实际部署时,需要根据具体需求选择合适的配置选项,以达到最佳性能和稳定性。

Global site tag (gtag.js) - Google Analytics