不是讲线程模型吗?和事件有什么关系?实际上 Redis 是一个事件驱动程序,大白话理解一下:就是通过事件的方式来运行 Redis 的。比如客户端向服务端发起一个 get 请求,在做好了建连、发送请求、响应请求、关闭连接等准备操作后,就触发了一个事件。所以在了解线程模型之前,先来看看事件。
Redis 的事件分为两种,分别是文件事件和时间事件两种。
文件事件是 socket 的一个抽象,客户端发送请求到服务端,会先建立连接,然后通过连接发送命令请求,其中每个连接就是一个 socket。对于一个 Redis 服务端,在同一时刻会有很多 socket 连接,每一个 socket 都可以理解成一个文件事件。
每产生一个文件事件后,就将其交给文件事件处理器去处理,文件事件处理器是由 I/O 多路复用处理器、文件事件分发器、事件处理器几部分组成。服务端在接收到请求后,是怎么工作的呢?
从上图可以看出,当客户端发送请求到服务端后;
I/O 对路复用处理器在 Redis 中用很多种实现,比如 epool、select、evport、kquene 等等,Redis 服务端在运行的时候会根据预先设定的 include 宏定义来选择效率最高的模型去处理网络事件。
以上基本上就是 Redis 的线程工作模型,不过还差一点就是文章开头讲到的另外一种事件类型,时间事件。
时间事件,顾名思义就是和时间相关的一些事件操作。举个例子,在 Redis 中最不陌生的应该就是各种定时处理器,每隔一段时间就出发一个操作。具体的应用如 RDB 和 AOF 文件定时做持久化操作;如果集群是主从架构的,定时将主库上的数据同步给从库,定期发送心跳信息给集群内各个节点,检查节点是否还在正常提供服务;定期检查库里面设置了过期时间的 key 并将已过期的 key 从内存中提出等等一些实际应用。
时间事件是怎么实现的?
Redis 将所有时间事件通过链表串联起来,每个结点代表一个时间事件,每个结点上存储着当前时间下一次要发生的时间点;每隔一段时间,该链表就会被遍历一次,发现那个时间事件该执行就去执行对应的事件,然后更新其下一次应该执行的时间点。
文件事件和时间事件是怎么配合工作的?
如上图,文件事件和时间事件配合工作流程图。
相信很多朋友已经知道了,2020 年 Redis 官方在 5 月份发布多了多线程版本,不过默认是不开启的,可通过 conf 配置开启。从目前 Redis 在实际生产环境中的使用情况看,其每秒钟支持的吞吐量已经非常高了。Redis 发展到目前,其主要的性能瓶颈主要在网络 I/O 和内存两个方面。