Redis作为一个非关系型数据库,除了在访问速度上拥有显著优势外,其本身支持的多种数据类型也非常有用,能覆盖系统开发中的很多应用场景。下面列举的场景有的是从网上其他人的博客里看到的,有的自己开发时尝试过的一些解决方案后记录下来的,希望能给以后的开发带来启发。

在说应用场景前先说一些是否觉得使用Redis的建议

使用建议

  • Redis 速度快是建立在内存数据库基础上的,但是一台服务器的内存要比磁盘金贵许多,所以在项目初期不要想什么都往 Redis 里放,这样当数据量上来后很快内存就会不够用,反而得不偿失。合理的利用有限的内存,将读(写)频繁的热数据放在 Redis 中才能更好感受到它带来的性能提升。

  • Redis 虽然提供了 RDB和 AOF两种持久化方式,但是普遍还是认为 Redis 的持久化并不是很靠谱。非常重要的数据不要依赖Redis来开发,或者最起码不要只在Redis中持久化

  • MySQL经过不断优化性能已经非常好,所以MySQL提供的数据结构和访问效率能满足的需求的情况下不要引入Redis,多引入一个组件就多一个可能的故障节点,尤其在保持数据一致性的场景中数据(比如用户余额)应该只放在数据库中,除非你知道怎么解决好系统的分布式事务。

缓存

作为 Key-Value形态的内存数据库,Redis 最先会被想到的应用场景便是作为数据缓存。而使用 Redis 缓存数据非常简单,只需要通过 string类型将序列化后的对象存起来即可,不过也有一些需要注意的地方:

  • 必须保证不同对象的 key 不会重复,并且使 key 尽量短,一般使用类名(表名)加主键拼接而成。

  • 选择一个优秀的序列化方式也很重要,目的是提高序列化的效率和减少内存占用。

  • 缓存内容与数据库的一致性,这里一般有两种做法:

  1. 只在数据库查询后将对象放入缓存,如果对象发生了修改或删除操作,直接清除对应缓存(或设为过期)。

  2. 在数据库新增和查询后将对象放入缓存,修改后更新缓存,删除后清除对应缓存(或设为过期)。

消息队列

Redis 中 list的数据结构实现是双向链表,所以可以非常便捷的应用于消息队列(生产者 / 消费者模型)。消息的生产者只需要通过 lpush将消息放入 list,消费者便可以通过 rpop取出该消息,并且可以保证消息的有序性。如果需要实现带有优先级的消息队列也可以选择 sortedset。而 pub/sub功能也可以用作发布者 / 订阅者模型的消息。无论使用何种方式,由于 Redis 拥有持久化功能,也不需要担心由于服务器故障导致消息丢失的情况。

时间轴(Timeline)

list作为双向链表,不光可以作为队列使用。如果将它用作栈便可以成为一个公用的时间轴。当用户发完微博后,都通过 lpush将它存放在一个 key 为 LATEST_WEIBOlist中,之后便可以通过 lrange取出当前最新的微博。

循环链表

list 还可以作为循环链表使用 RPOPLPUSH source destination

命令 RPOPLPUSH 在一个原子时间内,执行以下两个动作:

  • 将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。

  • 将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。

如果 sourcedestination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。

比如有个进程来完成派单任务,需要将用户发送过来的申请依次派发给工作人员,那么就可以把工作人员的身份标示维护在循环列表中,从列表尾部读取每次读取身份标示后相应的标示都会被放到列表头如此循环往复。

排行榜

使用 sortedset和一个计算热度的算法便可以轻松打造一个热度排行榜, zrevrangebyscore可以得到以分数倒序排列的序列, zrank可以得到一个成员在该排行榜的位置(是分数正序排列时的位置,如果要获取倒序排列时的位置需要用 zcard- zrank)。

计数器

计数功能应该是最适合 Redis 的使用场景之一了,因为它高频率读写的特征可以完全发挥 Redis 作为内存数据库的高效。在 Redis 的数据结构中, stringhashsortedset都提供了 incr方法用于原子性的自增操作,下面举例说明一下它们各自的使用场景:

  • 如果应用需要显示每天的注册用户数,便可以使用 string作为计数器,设定一个名为 REGISTERED_COUNT_TODAY的 key,并在初始化时给它设置一个到凌晨 0 点的过期时间,每当用户注册成功后便使用 incr命令使该 key 增长 1,同时当每天凌晨 0 点后,这个计数器都会因为 key 过期使值清零。

  • 每条微博都有点赞数、评论数、转发数和浏览数四条属性,这时用 hash进行计数会更好,将该计数器的 key 设为 weibo:weibo_id, hash的 field 为 like_number、 comment_number、 forward_number和 view_number,在对应操作后通过 hincrby使 hash中的 field 自增。

  • 如果应用有一个发帖排行榜的功能,便选择 sortedset吧,将集合的 key 设为 POST_RANK。当用户发帖后,使用 zincrby将该用户 id 的 score 增长 1。 sortedset会重新进行排序,用户所在排行榜的位置也就会得到实时的更新。

好友关系

这个场景最开始是是一篇介绍微博 Redis 应用的 PPT 中看到的,其中提到微博的 Redis 主要是用在在计数和好友关系两方面上,当时对好友关系方面的用法不太了解,后来看到《Redis 设计与实现》中介绍到作者最开始去使用 Redis 便是希望能通过 set解决传统数据库无法快速计算集合中交集这个功能。后来联想到微博当前的业务场景,确实能够以这种方式实现,所以姑且猜测一下:

对于一个用户 A,将它的关注和粉丝的用户 id 都存放在两个 set 中:

  • A:follow:存放 A 所有关注的用户 id

  • A:follower:存放 A 所有粉丝的用户 id

    那么通过 sinter命令便可以根据 A:followA:follower的交集得到与 A 互相关注的用户。当 A 进入另一个用户 B 的主页后, A:followB:follow的交集便是 A 和 B 的共同专注, A:followB:follower的交集便是 A 关注的人也关注了 B。

分布式锁

在 Redis 2.6.12 版本开始, stringset命令增加了三个参数:

  • EX:设置键的过期时间(单位为秒)

  • PX:设置键的过期时间(单位为毫秒)

  • NX | XX:当设置为 XX时,仅当 key 存在时才进行操作,设置为 NX时,仅当 key 不存在才会进行操作

    由于这个操作是原子性的,可以简单地以此实现一个分布式的锁,例如:

set key "lock" EX 1 NX

如果这个操作返回 false,说明 key 的添加不成功,也就是当前有人在占用这把锁。而如果返回 true,则说明得了锁,便可以继续进行操作,并且在操作后通过 del命令释放掉锁。并且即使程序因为某些原因并没有释放锁,由于设置了过期时间,该锁也会在 1 秒后自动释放,不会影响到其他程序的运行。

倒排索引

倒排索引是构造搜索功能的最常见方式,在 Redis 中也可以通过 set进行建立倒排索引,这里以简单的拼音 + 前缀搜索城市功能举例:

假设一个城市 北京,通过拼音词库将 北京转为 beijing,再通过前缀分词将这两个词分为若干个前缀索引,有:北京bbebeijinbeijing。将这些索引分别作为 set的 key(例如: index:北)并存储 北京的 id,倒排索引便建立好了。接下来只需要在搜索时通过关键词取出对应的 set并得到其中的 id 即可。

个人能力局限目前只知道这些数据类型的应用场景,如果各位有其他场景的应用经验欢迎交流补充,另外面试时被问到为何使用Redis不要简单的说因为快, 如果在系统中只使用了缓存这一个应用场景那么最起码可以提供一些MySQL的QPS和Redis的QPS数据或者程序在Redis使用前后的平均响应时长来印证你的观点。

Redis应用场景汇总相关推荐

  1. Redis的应用场景汇总

    Redis应用场景 Redis作为一个非关系型数据库,除了在访问速度上拥有显著优势外,其本身支持的多种数据类型也非常有用,能覆盖系统开发中的很多应用场景.下面列举的场景有的是从网上其他人的博客里看到的 ...

  2. AliCloudDB for redis应用场景之存储最新N条聊天记录

    AliCloudDB for redis应用场景之存储最新N条聊天记录 场景介绍 在各种IM通信工具中,常常需要展示最新的聊天记录,这种数据写入频繁,对响应时间要求高.一般情况,这种场景通常会选择持久 ...

  3. Redis应用场景说明与部署

    Redis简介 REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统.redis和大名鼎鼎的memcached缓存服务很像,但是red ...

  4. Redis与Memcached汇总

       谈谈Memcached与Redis  1. Memcached简介 Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric为首开发的 ...

  5. Redis使用场景、Redis线程模型、Redis持久化 - 公开课笔记

    redis和数据库怎么写同步? 分布式如何达到一致性? CAP 一致性.可用性.性能 HA:高可用,不存在没有任何时延.没有任何波动的高可用 容忍度只要达标,就可以.不要为了技术而技术->你会否 ...

  6. 转载:Redis 应用场景

    2019独角兽企业重金招聘Python工程师标准>>> 1.  MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载 ...

  7. Redis应用场景(转)

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

  8. Redis 面试题汇总

    1.Redis 使用场景有哪些? 答:Redis 使用场景如下: 记录帖子点赞数.点击数.评论数 缓存近期热帖 缓存文章详情信息 记录用户会话信息 2.Redis 有哪些功能? 答:Redis 功能如 ...

  9. redis 数据类型详解 以及 redis适用场景场合

    redis 数据类型详解 以及 redis适用场景场合 1. MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访 ...

最新文章

  1. Ubuntu 13.10 安装软件失败后出现的问题——已安装 post-installation 脚本 返回了错误号 1...
  2. AWS ML deploy platform
  3. vue.js几行实现的简单的todo list
  4. 做科研没人带,发不了文章怎么办?
  5. 为什么基于内容的读取缓存 (CBRC) 对于 Horizon View 和 VSAN 如此重要?
  6. struts2第一个程序 Helloworld
  7. zabbix 监控项-计算公式监控磁盘使用率
  8. CSS选择器详解(转)
  9. Mybatis学习之接口编程
  10. 建模方法(四)-因子分析定义和应用
  11. 《信息安全技术—个人信息安全影响评估指南》pdf下载
  12. cad计算机配置要求,CAD对电脑配置有什么要求?CAD对电脑配置有什么要求?
  13. MT6573 android 系统默认语言处理流程
  14. 不同Ubuntu版本,对应ROS版本
  15. linux上启动eureka集群服务,SpringCloud@Docker系列: 运行Eureka Server集群
  16. kindle长时间不用,屏幕显示电池感叹号,一直充电没反应,试了网上的方法都不好用,到亚马逊官网找到了解决办法
  17. 吴军给女儿的信:乐观的人生态度,比什么都重要
  18. 神舟笔记本电脑降低声音
  19. 小播本地音乐功能指引
  20. Failed to resolve: com.github.chrisbanes:PhotoView:1.2.6 Show in File Show i

热门文章

  1. security NO.1
  2. Recurrent Neural Network系列1--RNN(循环神经网络)概述
  3. Visual Studio 2010旗舰版正式版序列号 - civilman的专栏 - 博客频道 - CSDN.NET
  4. 原生js-Ajax jq-Ajax集结
  5. WPF中路由事件的传播
  6. 外网DNS系统外网访问及邮件系统外网域名访问问题
  7. [官版翻译]OpenStack centos版安装(二)
  8. PhoneGap学习地址 / PhoneGap API介绍:Events
  9. Windows7 登陆失败:未知的用户名或密码错误 网络共享文件夹
  10. 优化MySQL的数据库性能的八种方法