Redis「5」事件处理模型与键过期策略
01-Redis 单线程模型
Redis 服务端是基于 Reactor 模式实现的事件驱动程序,并需要处理两类的事件:
文件事件,简单来讲就是 Redis 客户端通过 Socket 发来的命令。
时间事件,服务端中需要特定时间点执行的操作,例如
serverCron
函数。
Redis 的单线程模型实际指的是上述两类事件是在同一个线程内处理的。但是为了能同时处理多个客户端的连接,Redis 中用到了 IO 多路复用技术。《Redis 设计与实现》中对 Redis 中的多路复用介绍如下:
文件事件处理器以单线程方式运行,但通过 IO 多路复用程序来监听多个客户端套接字。既实现了高性能的网络通信模型,又可以很好地与 Redis 服务器中其他同样以单线程方式运行的模块进行对接,这保持了 Redis 内部线程模型的简单性。
Redis 中单线程的事件循环可以用如下伪代码表示:
01.1-文件事件处理器
当 Socket 变得可读时,会产生
AE_READABLE
事件当 Socket 变得可写时,会产生
AE_WRITABLE
事件
一次完整的客户端与服务端连接过程中,事件及处理器的过程如下:
服务端监听套接字
AE_READABLE
事件,且此时该事件对应的处理器为连接应答处理器;当客户端发起连接后,监听套接字将产生
AE_READABLE
事件,连接应答处理器负责创建客户端套接字,并将客户端套接字的AE_READABLE
事件与命令请求处理器绑定;当客户端发送命令时,客户端套接字将发生
AE_READABLE
事件,命令请求处理器负责处理这些命令,并产生回复。为了将命令回复传送到客户端,服务器会将客户端套接字的
AE_WRITABLE
事件与命令回复处理器绑定。当客户端尝试读取命令回复时,会触发
AE_WRITABLE
事件,命令回复处理器会将回复写入套接字。之后,服务器会解除AE_WRITABLE
事件与命令回复处理器的绑定。
01.2-时间事件处理器
Redis 中时间事件分为 2 类:
定时事件,例如 30ms 后执行一次
周期事件,例如每隔 30ms 执行一次
每隔时间事件,都包含如下三个要素:
id,全局唯一 ID,且按照事件先后顺序递增。
when,事件到达时间,毫秒精度 UNIX 时间戳。
timeProc,事件处理器,用于处理响应的事件。其返回值决定事件是定时的(
ae.h/AE_NOMORE
),还是周期性的。
[1] Reactor pattern (Node.js Netty 等知名项目的线程模型也都基于 Reactor 模式)
02-键过期
Redis 中设置键过期的方式有如下几种:
expire key ttl,ttl 秒后过期
pexpire key ttl,ttl 毫秒后过期
pexpireat key timestamp,在 timestamp 时刻过期
无论上述哪种方式,最终都通过pexpireat
方式实现。过期的实现原理如下:在redisDb
中维护了一个 dict(过期字典),记录了哪些键在何时应当过期。
过期判定的原则就是,将过期字典中的键对应的值与当前系统时间相比,若小于系统时间,则认为键过期。
02.1-键过期删除策略
一般来说,键过期删除策略有三种:
定时删除,在设置键的过期时间时,启动一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除。优缺点:对内存最友好,但对 CPU 最不友好。
惰性删除,过期时并不删除,但是每次从键空间获取键时,都判断键是否过期。若过期则删除,否则返回该键的值。对内存不友好,但对 CPU 友好。
定期删除,每隔一段时间就对数据库进行检查,删除里面的过期键。(前两种方式的混合)。
02.2-Redis 内存淘汰机制
虽然 Redis 通常采用惰性删除和定期删除的混合策略,但仍有可能有大量过期的键驻留在内存中,导致 OOM。Redis 是如何解决这个问题的呢?你可能需要了解如下几种 Redis 的内存淘汰机制:
volatile-lru,从
server.db[i].expires
中挑选最近最少使用的淘汰;volatile-ttl,从
server.db[i].expires
中挑选将要过期的数据淘汰;volatile-random, 从
server.db[i].expires
中随机挑选数据淘汰;allkeys-lru,从
server.db[i].dict
中挑选最近最少使用的淘汰;allkeys-random,从
server.db[i].dict
中随机挑选数据淘汰;no-eviction,如果内存不足以写入新数据,拒绝淘汰,写入报错;
volatile-lfu,从
server.db[i].expires
中挑选最不经常使用的淘汰;allkeys-lfu,从
server.db[i].dict
中挑选最不经常使用的淘汰;
历史文章
版权声明: 本文为 InfoQ 作者【Samson】的原创文章。
原文链接:【http://xie.infoq.cn/article/71bd158788f6137e0b9c44191】。文章转载请联系作者。
评论