关闭

Redis常见应用场景介绍

标签: redis
94人阅读 评论(0) 收藏 举报
分类:

在主页中显示最新的项目列表

在Web应用中,“列出最新的XXX”非常普遍,这通常会带来可扩展性问题。 类似的问题就可以用Redis来解决。比如说,一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论。假设数据库中的每条评论都有一个唯一的递增的ID字段,就可以使用分页来制作主页和评论页,使用Redis的模板,每次新评论发表时,我们会将它的ID添加到一个Redis列表。操作如下:

  1. Redis保存最新的评论LPUSH latest.values xxx_id
  2. Redis删除多余的列表数据,只保存最新的5000条LTRIM latest.values 0 5000
  3. 获取最新评论的范围数据时,通过一次遍历获取需要的评论redis.lrange(“latest.values”,0,100)

Redis中我们的最新ID使用了常驻缓存,这是一直更新的,但是我们做了限制不能超过5000个ID,因此我们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才需要去访问数据库

排行榜相关

一个很普遍的需求是排行榜(leader board)按照得分进行排序,各种数据库的数据并非存储在内存中,因此在按得分排序以及实时更新这些要求在数据库的性能不够理想;而这些操作对于Redis来说很简单,即使你有几百万个用户,每分钟都会有几百万个得分更新。比如那些在线游戏的排行榜,比如一个Facebook的游戏,根据得分你通常想要:列出前100名高分选手,列出某用户当前的全球排名

  1. 使用zset存储用户及得分 ZADD leaderboard <score> <username>
  2. 得到得分最高的100名用户 ZREVRANGE leaderboard 0 99
  3. 得到得分最低的100名用户 ZRANGE leaderboard 0 99
  4. 得到个人总排名 ZRANK leaderboard <username>

按照用户投票和时间排序

针对得分随时间变化的排序问题,如热点新闻等。新闻按照类似下面的公式根据得分来排序,计算方式:
score = points / time^alpha
因此用户的投票会相应的把新闻挖出来,但会按照时间的指数将新闻埋下去。 每次新的新闻贴上来后,我们将ID添加到列表中,使用LPUSH + LTRIM,确保只取出最新的1000条项目

  1. 存储最新的新闻列表LPUSH latest.news <news>
  2. 限制保存最新的1000条LTRIM latest.news 0 1000
  3. 新闻被点击后使用zset存储得分及新闻 ZADD score.news <score> <news> ,得分=点击数/发布时长^2
  4. 删除ZADD中非最新的新闻 ZREM score.news <news> [<news>]
  5. 得到得分最低的100名用户 ZRANGE score.news 0 99
  6. 得到得分最高的100名用户 ZREVRANGE score.news 0 99
  7. 得到新闻总排名 ZRANK score.news <news>

过期项目处理

还有一种常用的排序是按照时间排序,项目中使用unix时间作为得分,用来保持列表按时间排序,周期检查排序列表,发现过期的项目则删除。每次有新记录添加时,把它加入到排序集合中,用时间属性current_time和time_to_live;使用ZRANGE…SCORES通过分数返回有序集合指定区间内的成员。如果发现unix时间已经过期,则在持久化数据库中删除。

  1. 存储最新的项目,用户时间作为得分 ZADD last.items <current_time+time_to_live> <item>
  2. 检查项目过期,获取小于当前时间的项目 ZRANGEBYSCORE last.items -inf <current_time>
  3. 删除过期项目 zrem

计数

各种数据的计数和统计需求用途广泛,比如想知道什么时候封锁一个IP地址。INCRBY命令让这些变得很容易,通过原子递增保持计数;GETSET用来重置计数器;过期属性用来确认一个关键字什么时候应该删除。
比如我想要知道某些特定的IP地址,到底有多少访问了某篇文章:

  1. 获得页面每日浏览量时需要这样做 INCR page:<day>:<page_id>
  2. 获得用户访问页面量 INCR user:<user_id>

特定时间内的特定项目

Redis统计在某段特点时间里有多少特定用户访问了某个特定资源。比如我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章。

  1. 每次获得一次新的页面浏览时只需要这样做 SADD page:
  2. 获取特定用户的数量 SCARD page:<time>:<page_id>
  3. 测试某个特定用户是否访问了这个页面SISMEMBER page:<time>:<page_id> <user_id>
  4. 获取特定页面的所有访问用户 SMEMBERS page:<time>:<page_id>

队列

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

  1. 加入数据到队列 LPUSH <key> <value>
  2. 获取数据从队列 LPOP <key>
  3. 获取队列范围数据 LRANGE <key> 0 10

缓存

Redis能够替代memcached,让你的缓存从只能存储数据变得能够更新数据,因此你不再需要每次都重新生成数据了。网络应用不能无休止地进行模型的战争,看看这些Redis的原语命令,尽管简单但功能强大,把它们加以组合,所能完成的就更无法想象。当然,你可以专门编写代码来完成所有这些操作,但Redis实现起来显然更为轻松

示例

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:12826次
    • 积分:223
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类