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

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

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

1、显示最新的项目列表

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

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

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

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

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

我们可以使用分页来制作主页和评论页,使用Redis的模板,每次新评论发表时,我们会将它的ID添加到一个Redis列表:

LPUSH latest.comments

我们将列表裁剪为指定长度,因此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数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。

2、删除与过滤

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

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

3、排行榜相关

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

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

– 列出前100名高分选手

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

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

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

ZADD leaderboard

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

得到前100名高分用户很简单:

ZREVRANGE leaderboard 0 99

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

ZRANK leaderboard 

4、按照用户投票和时间排序

排行榜的一种常见变体模式就像Reddit或Hacker News用的那样,新闻按照类似下面的公式根据得分来排序:

score = points / time^alpha

因此用户的投票会相应的把新闻挖出来,但时间会按照一定的指数将新闻埋下去。下面是我们的模式,当然算法由你决定。

模式是这样的,开始时先观察那些可能是最新的项目,例如首页上的1000条新闻都是候选者,因此我们先忽视掉其他的,这实现起来很简单。

每次新的新闻贴上来后,我们将ID添加到列表中,使用

LPUSH + LTRIM,确保只取出最新的1000条项目。

有一项后台任务获取这个列表,并且持续的计算这1000条新闻中每条新闻的最终得分。计算结果由ZADD命令按照新的顺序填充生成列表,老新闻则被清除。这里的关键思路是排序工作是由后台任务来完成的。

5、处理过期项目

另一种常用的项目排序是按照时间排序。我们使用unix时间作为得分即可。

模式如下:

– 每次有新项目添加到我们的非Redis数据库时,我们把它加入到排序集合中。这时我们用的是时间属性,current_time和time_to_live。

– 另一项后台任务使用ZRANGE…SCORES查询排序集合,取出最新的10个项目。如果发现unix时间已经过期,则在数据库中删除条目。

6、计数

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

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

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

例如这样操作:

INCR user: EXPIRE
user: 60

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

7、特定时间内的特定项目

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

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

SADD page:day1:

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

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

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

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

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

9、Pub/Sub

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

10、队列

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

现代的互联网应用大量地使用了消息队列(Messaging)。消息队列不仅被用于系统内部组件之间的通信,同时也被用于系统跟其它服务之间的交互。消息队列的使用可以增加系统的可扩展性、灵活性和用户体验。非基于消息队列的系统,其运行速度取决于系统中最慢的组件的速度(注:短板效应)。而基于消息队列可以将系统中各组件解除耦合,这样系统就不再受最慢组件的束缚,各组件可以异步运行从而得以更快的速度完成各自的工作。

此外,当服务器处在高并发操作的时候,比如频繁地写入日志文件。可以利用消息队列实现异步处理。从而实现高性能的并发操作。

11、缓存

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

此部分内容来自 http://blog.csdn.net/niucsd/article/details/50966733

redis应用场景及实例的更多相关文章

  1. 详解 Redis 应用场景及应用实例

    redis(二)高级用法 详解 Redis 应用场景及应用实例 Redis 它是什么?它用来做什么?它的优势与短板如何? 告诉你Redis是一个牛逼货

  2. Redis应用场景-转载

    1.  MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的 ...

  3. Redis应用场景(转)

    (来源:http://www.cnblogs.com/shanyou/archive/2012/09/04/2670972.html) Redis常用数据类型 Redis最为常用的数据类型主要有以下五 ...

  4. redis使用场景

    Redis应用场景   Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作 ...

  5. <转>Redis 应用场景

    http://blog.csdn.net/hguisu/article/details/8836819 1.  MySql+Memcached 架构的问题 Memcached采用客户端-服务器的架构, ...

  6. Redis应用场景 及其数据对象 string hash list set sortedset

    原文地址:http://www.cnblogs.com/shanyou/archive/2012/09/04/2670972.html Redis开创了一种新的数据存储思路,使用Redis,我们不用在 ...

  7. Redis应用场景-整理

    1.  MySql+Memcached架构的问题 Memcached采用客户端-服务器的架构,客户端和服务器端的通讯使用自定义的协议标准,只要满足协议格式要求,客户端Library可以用任何语言实现. ...

  8. 【*】Redis实战场景中相关问题

    一.Redis简介 redis主要解决的问题 分布式缓存是分布式系统中的重要组件,主要解决高并发.大数据场景下,热点数据访问的性能问题,提供高性能的数据快速访问. 使用缓存常见场景 项目中部分数据访问 ...

  9. ehcache、redis应用场景比较

    应用场景: ehcache是Hibernate中默认的CacheProvider,直接在jvm虚拟机中缓存,速度快,效率高:但是缓存共享麻烦,集群分布式应用不方便.  . 缓存数据有两级:内存和磁盘, ...

随机推荐

  1. 奇怪的Unrooted Tests错误

    错误如图: 条件如下: Eclipse里的Maven工程. 使用JUnit4(这个是否必须不知,反正我的工程用的4) 修改某个Test类里的方法名,或者增加一个Test方法. 现象: 在MyEclip ...

  2. 显示 Mac隐藏的文件夹 命令语句

    默认情况下,模拟器的目录是隐藏的,要想显示出来,需要在Mac终端输入下面的命令 显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFil ...

  3. systemd 中的requires, wants, before, after

    man systemd.unit    man systemd.service ###依赖关系和前后顺序* 依赖关系:Requires和Wants * 前后顺序:After,Before 依赖关系,前 ...

  4. python读取txt写入txt

    http://www.cnblogs.com/allenblogs/archive/2010/09/13/1824842.html

  5. 常用的ES6语法

    1. let.const 和 block 作用域 let 允许创建块级作用域,ES6 推荐在函数中使用 let 定义变量,而非 var: var a = 2; { let a = 3; console ...

  6. NOIP2018 全国热身赛 第二场 (不开放)

    NOIP2018 全国热身赛 第二场 (不开放) 题目链接:http://noi.ac/contest/26/problem/60 一道蛮有趣的题目. 然后比赛傻逼了. 即将做出来的时候去做别的题了. ...

  7. LeetCode954二倍数对数组

    问题:二倍数对数组 给定一个长度为偶数的整数数组 A,只有对 A 进行重组后可以满足 “对于每个 0 <= i < len(A) / 2,都有 A[2 * i + 1] = 2 * A[2 ...

  8. node.js express环境下中文需要注意的地方

    问题一: 最近在nuxt项目中开始着手把一些跨域的请求转移到express里,其实跟其他语言差不多,http对象发请求,接收请求都写得很顺畅.之前用的请求部分大多数是get请求,所以除了注意编码问题之 ...

  9. ZendFramework-2.4 源代码 - 关于MVC - View层 - 在模板内渲染子模板

    <?php // 方式一: // 1.在模板内直接编写如下内容即可 $viewModel = new ViewModel(); $viewModel->setTemplate('album ...

  10. myeclipse10.5 crack(2012-12-27-bd 写的日志迁移

    首先去网上下一个破解文件如图: 解压过后打开的文件夹如图: 再打开crack文件夹如图: 运行run.bat如果点击它没反应就是你没有安装jdk,它如果运行就如图所示: 到这一步就在第一个方框user ...