Redis的网络IO和键值对的读写都是由主线程完成的,如果主线程操作消耗时间太长,就会引起主线程阻塞。
Redis实例的阻塞点
- 客户端:网络IO,键值对增删改操作,数据库操作
- 磁盘:生成RDB快照,记录AOF日志,AOF重写
- 主从节点:主库生成,传输RDB文件,从库接受RDB文件、清空数据库、加载RDB 文件
- 切片集群实例:向其他实例传输哈希槽信息,数据迁移
汇总

客户端交互的阻塞点
- 集合全量查询和聚合操作
- 复杂度为O(N) 的操作都会阻塞
- bigkey 删除操作
- 删除操作会释放内存,而释放的内存会插入到一个空闲内存块表中,这个过程会阻塞释放内存的进程
- 清空数据库
- 删除键值都有阻塞风险那么删除数据库就更是有阻塞风险了
磁盘交互阻塞点
Redis 设计采用子进程进行RDB 文件生成,以及AOF 日志重写这样慢速的磁盘IO就不会阻塞主进程
- AOF日志同步写:一个同步写磁盘操作耗时1~2ms ,如果有大量的写操作记录在AOF日志中,并同步回写的话,就会阻塞主线程
主从节点交互阻塞点
- 加载RDB文件:清空当前数据库后,还需要RDB文件加载到内存中,如果RDB文件大,加载过程慢
切片集群实例交互时的阻塞点
使用Redis Cluster 方案,在迁移过程中有bigkey 的话,会造成组线程阻塞,因为Redis Cluster 使用了同步迁移
可以异步的阻塞点
针对5个阻塞点,除了全量查询和聚合操作 和 从库加载RDB 文件,其他三个阻塞点都可以使用异步子线程机制实现 bigkey 删除、清空数据库、AOF日志同步写
异步子线程机制
Redis 主线程启动后,会调用操作系统提供过的pthread_create 创建3个子线程,分别负责AOF日志写操作、键值对删除、文件关闭的异步执行

4.0 之后异步删键值对和数据库的清空操作
- UNLINK 删除大量元素
- FLUSHDB 和 FLUSHALL 加ASYNC 可以异步执行
