Redis 4.x系列(一):Redis介绍及应用场景
Redis 在现在互联网应用中已非常流行,在整个缓存技术领域占了很大的比重,大的互联网应用甚至部署上千个 Redis 实例。
Redis 官网,Redis 中文网,国内还有一些关于 Redis 的站点,不过描述的 Redis 版本都偏低。
工作有些年,做过的项目几乎都有用到 Redis, 零零散散也写过一些笔记,比较碎片而不成体系,现在 Redis 4.0.x 版本已稳定,新的 5.0 rc 版本也已发布,而 Redis 4.0.x 版本的一些新特性并没有系统了解和实践,知识需要演进,围绕 4.0.x版本,在实践中理解和学习。
Redis 介绍
Redis(REmote DIctionary Server) 是一个开源的基于内存键值对数据结构的服务器;可以用作数据库、缓存、消息代理。Redis 支持多种数据类型和强大的API功能,可以搭建集群和持久化数据。
Redis 基于内存的数据存储,最大程度利用了单线程、非阻塞、多路复用的I/O模型来快速处理请求,具有性能高的优点, 在高并发、低延迟的系统中使用越来越广。某些情况下也会创建线程或子线程来处理某些任务。
Redis 包含了一个简单但强大的异步事件库,称为 ae
。该库中封装了不同操作系统的polling
机制(即非阻塞I/O相关机制),如epoll, kqueue, select
等。
Redis事件模型
以 Linux 中 I/O 多路复用模型的 epoll
为例,这也是 Redis 默认使用的方式。
- 首先,调用
epoll_create
通知操作系统内核要使用epoll。 - 然后,调用
epoll_ctl
把文件描述符(FD)和关注的事件类型传给内核。 - 之后,调用
epoll_wait
等待通过epoll_ctl所设置的文件描述符上发生所关注的事件。当文件描述符被更新时,内核会向应用程序发送通知。 - 应用层唯一需要做的是为关注的事件创建事件处理函数/回调函数。
I/O多路复用:一个线程,通过记录 I/O 流的状态来同时管理多个 I/O。在polling
的过程中没有线程或子进程的创建和交互。因此,该模型的关键优点就在于它是一个轻量级上下文切换的 I/O 模型,在上下文切换上花费的代价不大。
常见应用场景
会话存储
在 Web应用服务集群部署的架构中,Session
通常需要存储在外部存储系统中,共享给集群应用。对 Redis 的访问延迟非常低,Spring Session 默认就支持 Redis 来保存 Session 数据,只需极简单的配置即可使用;Redis 对键过期的支持天然地适用于会话的超时时间管理,所以 Redis 堪称是完美的会话存储机制。
计数统计
Redis 还可用于分析和统计的场景。例如,统计在线用户数,创建 Session 时使用INCR
命令增加计数器,Session 销毁时使用DECR
命令减少计数器即可。Redis 命令都是原子的,所以无需担心竞态。
基于HASH、Sort Set、HyperLoglog
等数据类型,可还可构建更高级的计数器或统计数据捕获系统。
示例:
- 统计视频播放数,用户每播放一次视频,对应的视频播放数就自增 1。
- 真实的计数系统还需要考虑防作弊、按不同维度计数、持久化。
限速
限速场景的使用实际是计数统计的的场景扩展。例如为防止短信接口不被频繁访问,可以限制用户每分钟获取验证码的频率,如一分钟不能超过5次。
1 | //伪代码 |
排行榜
Redis 的有序集合数据类型可以轻构地实现一个排行榜,例如可以将投票数、购买数、收藏数、好评数等作为权重来对数据进行排序,可以使用ZREVRANGE
命令按照升序或降序返回列表,这可比诸如 MySQL 关系数据库中的实现高效的多了。
队列
Redis 的列表(list)类型支持左右两端插入和删除的操作,非常适用于实现简单的对列。还可使用RPOPLPUSH
命令实现可靠的队列(注:可靠是相对的)。
缓存
Redis 是基于内存的数据存储系统,可以用于关系数据库的前面作为缓存来使用,在查关系数据库之前先从 Redis 缓存取数据,若 Redis 中不存再从关系数据库中查询数据,并存入到 Redis 中以供下次使用,降低关系数据库的压力。
Redis 作为缓存使用,数据的大小受限于内存的大小,为了限制缓存的大小和高效地利用内存空间,可以对缓存中的记录设置过期时间或应用诸如**最少使用(LRU:Least Recently Used)**的收回策略。
示例:
- 先从 Redis 中获取数据,如果没有,执行第二步,有则返回。
- 如果没有,再从数据库中获取,并回写到 Redis。
- 如果回写的数据需要过期限制则加上过期时间。
最新的 N 个记录
Redis 的列表类型提供了 LTRIM
命令,可以限制列表始终包含 N 条数据:ltrim key start stop
。
相关参考
Redis 4.x系列(一):Redis介绍及应用场景
http://blog.gxitsky.com/2018/09/20/Redis-1-introduction-application-scenario/