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 默认使用的方式。

  1. 首先,调用epoll_create通知操作系统内核要使用epoll
  2. 然后,调用epoll_ctl把文件描述符(FD)和关注的事件类型传给内核。
  3. 之后,调用epoll_wait等待通过epoll_ctl所设置的文件描述符上发生所关注的事件。当文件描述符被更新时,内核会向应用程序发送通知。
  4. 应用层唯一需要做的是为关注的事件创建事件处理函数/回调函数。

I/O多路复用:一个线程,通过记录 I/O 流的状态来同时管理多个 I/O。在polling的过程中没有线程或子进程的创建和交互。因此,该模型的关键优点就在于它是一个轻量级上下文切换的 I/O 模型,在上下文切换上花费的代价不大。
I/O多路复用模型图  

常见应用场景

会话存储

在 Web应用服务集群部署的架构中,Session通常需要存储在外部存储系统中,共享给集群应用。对 Redis 的访问延迟非常低,Spring Session 默认就支持 Redis 来保存 Session 数据,只需极简单的配置即可使用;Redis 对键过期的支持天然地适用于会话的超时时间管理,所以 Redis 堪称是完美的会话存储机制。

计数统计

Redis 还可用于分析和统计的场景。例如,统计在线用户数,创建 Session 时使用INCR命令增加计数器,Session 销毁时使用DECR命令减少计数器即可。Redis 命令都是原子的,所以无需担心竞态。

基于HASH、Sort Set、HyperLoglog等数据类型,可还可构建更高级的计数器或统计数据捕获系统。

示例:

  1. 统计视频播放数,用户每播放一次视频,对应的视频播放数就自增 1。
  2. 真实的计数系统还需要考虑防作弊、按不同维度计数、持久化。

限速

限速场景的使用实际是计数统计的的场景扩展。例如为防止短信接口不被频繁访问,可以限制用户每分钟获取验证码的频率,如一分钟不能超过5次。

1
2
3
4
5
6
7
//伪代码
isExists = redis.set(key,1,"ex 60","nx");
if(isExists != null || redis.incr(key) <= 5){
//通过
}else{
//限速
}

排行榜

Redis 的有序集合数据类型可以轻构地实现一个排行榜,例如可以将投票数、购买数、收藏数、好评数等作为权重来对数据进行排序,可以使用ZREVRANGE命令按照升序降序返回列表,这可比诸如 MySQL 关系数据库中的实现高效的多了。

队列

Redis 的列表(list)类型支持左右两端插入和删除的操作,非常适用于实现简单的对列。还可使用RPOPLPUSH命令实现可靠的队列(注:可靠是相对的)。

缓存

Redis 是基于内存的数据存储系统,可以用于关系数据库的前面作为缓存来使用,在查关系数据库之前先从 Redis 缓存取数据,若 Redis 中不存再从关系数据库中查询数据,并存入到 Redis 中以供下次使用,降低关系数据库的压力。

Redis 作为缓存使用,数据的大小受限于内存的大小,为了限制缓存的大小和高效地利用内存空间,可以对缓存中的记录设置过期时间或应用诸如**最少使用(LRU:Least Recently Used)**的收回策略。

示例:

  1. 先从 Redis 中获取数据,如果没有,执行第二步,有则返回。
  2. 如果没有,再从数据库中获取,并回写到 Redis。
  3. 如果回写的数据需要过期限制则加上过期时间。

最新的 N 个记录

Redis 的列表类型提供了 LTRIM 命令,可以限制列表始终包含 N 条数据:ltrim key start stop

相关参考

IO模式和IO多路复用
漫谈五种IO模型(主讲IO多路复用)
Redis IO多路复用技术以及epoll实现原理

作者

光星

发布于

2018-09-20

更新于

2022-08-14

许可协议

评论