Redis 线程、持久化和监控
Redis线程模型
Redis主线程模型
图1 Redis 6.0之前的主线程模型
IO多路复用程序指的是单个线程监听多个套接字连接(Socket),当IO多路复用程序将多个Socket上的就绪事件放置于队列中, Redis主线程一次处理队列中事件,事件类型包括命令请求处理器(读取客户端发送指令,执行指令逻辑),命令回复处理器(向客户端发送响应),连接应答处理器(同客户端建立连接)。
Redis 使用单主线程原因(官方回应):
- 在使用 Redis 时,Redis 主要受限是在内存和网络上,CPU 几乎没有性能瓶颈的问题。
- 以Linux 系统为例子,在Linux系统上Redis 通过 pipelining 可以处理 100w 个请求每秒,而应用程序的计算复杂度主要是 O(N) 或 O(log(N)) ,不会消耗太多 CPU。
- 使用了单线程后,提高了可维护性。多线程模型在某些方面表现优异,却增加了程序执行顺序的不确定性,并且带来了并发读写的一系列问题,增加了系统复杂度。同时因为线程切换、加解锁,甚至死锁,造成一定的性能损耗。
- Redis 通过 AE 事件模型以及 IO 多路复用等技术,拥有超高的处理性能,因此没有使用多线程的必要。
IO线程组模型
随着硬件的发展,单个线程处理网络读写的速度跟不上底层网络硬件的速度。Redis引入了IO线程组来使用多线程处理IO读写事件,而命令执行依然是在单主线程中执行。
图2 主线程+IO线程组模型
后台线程
Redis主线程执行命令处理、Key过期删除、rehash等操作,还存在以下后台进程:
- BIO_CLOSE_FILE:关闭文件,负责释放套接字
- BIO_AOF_FSYNC:异步持久化aof文件。
- BIO_LAZY_FREE:内存空间的懒释放(针对前期删除仅仅删除引用,并不释放空间)
Redis 持久化
Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍哦),最后再将临时文件替换之前的备份文件。Redis的持久化建议都开启RDB和AOF模式。RDB用于数据备份,作为最后备份手段。
RDB模式
RDB 是 Redis 默认的持久化方案。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。
以下情况会触发RDB:
1 在指定的时间间隔内,执行指定次数的写操作
2 执行save(阻塞, 只管保存快照,其他的等待) 或者是bgsave (异步)命令
3 执行flushall 命令,清空数据库所有数据,意义不大。
4 执行shutdown 命令,保证服务器正常关闭且不丢失任何数据。
AOP模式
AOF :默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
Redis 监控
slowlog
配置(config set/get):
slowlog-log-slower-than: 慢查询阈值
slowlog-max-len: 慢查询最多保存条数
config get slowlog-log-slower-than: 获取慢查询阈值
查看慢查询:Slowlog get 10: 获取前n条慢查询
返回结果:
- 唯一标识
- 记录时间
- 查询耗时,单位微妙
- 执行命令
Slowlog len: 当前日记总量
Slowlog reset:清除日记
OPS:Operations Per Second
Info stats返回的instantaneous_ops_per_sec字段
命中率
Info stats 获取命中次数和未命中次数计算命中率
HitRate=keyspace_hits/(keyspace_hits+keyspace_misses)
内存情况
Info memory 命令查看Redis内存状态。如 used_memory: 使用内存。