影响Redis性能的5大方面的潜在因素
- Redis内部的阻塞式操作
- CPU核和NUMA架构的影响
- Redis关键系统配置
- Redis内存碎片
- Redis缓冲区
Redis实例有哪些阻塞点
- 客户端:网络IO,键值对增删改查操作,数据库操作
- 磁盘:生成RDB快照,记录AOF日志,AOF日志重写
- 主从节点:主库生成、传输RDB文件,从库接收RDB文件,清空数据库,加载RDB文件
- 切片集群实例:向其他实例传输哈希槽信息,数据迁移
客户端操作阻塞点
- 网络IO部分,redis使用IO多路复用机制,避免主线程一直处于等待网络链接或请求到来的状态
- 键值对增删改查操作,如果操作复杂度或者操作所需时间复杂度比较高的话,会阻塞redis
- 集合全量查询和聚合操作 hgetall smembers
- 删除bigkey也会造成阻塞,删除内存释放空间时,操作系统会向释放掉的内存块中插入一个链表,用于空闲内存管理
- 清空数据库相比删除会更影响redis
磁盘交互阻塞点
- AOF日志同步写
主从节点交互阻塞点
- 主库复制内存,创建和传输rdb文件都是有子进程完成的,但是从库清空数据库会造成从库阻塞
- 从库加载RDB文件,文件越大加载过程越慢,加载RDB文件就成为了阻塞点
切片集群实例交互阻塞点
- redis cluster模式同步迁移bigkey
异步子线程机制
- redis主线程启动后创建3个子线程负责AOF日志重写,键值对删除以及文件异步关闭
- 主线程通过一个链表形式的任务队列和子线程进行交互。当收到键值对删除和清空数据库的操作时,主线程会把这个操作封装成一个任务,放入到任务队列中,然后给客户端返回一个完成信息,表明删除已经完成。这种异步删除也被称为惰性删除,此时删除或清空操作不会阻塞主线程,这就避免了对主线程的性能影响
- AOF 日志配置成 everysec,主线程会把 AOF 写日志操作封装成一个任务,也放到任务队列中。后台子线程读取任务后,开始自行写入 AOF 日志,主线程不用一直等待 AOF 日志写完
- 键值对删除:集合类型中有大量元素(例如有百万级别或千万级别元素)需要删除时,使用 UNLINK 命令
- 清空数据库:可以在 FLUSHDB 和 FLUSHALL 命令后加上 ASYNC 选项,让后台子线程异步地清空数据库