Redis 性能的 5 大方面的潜在因素,分别是:

  • Redis 内部的阻塞式操作;
  • CPU 核和 NUMA 架构的影响;
  • Redis 关键系统配置;
  • Redis 内存碎片;
  • Redis 缓冲区。

Redis 内部的阻塞式操作

Redis 实例有哪些阻塞点

和客户端交互时的阻塞点

Redis 使用了 IO 多路复用机制,网络 IO 不是导致 Redis 阻塞的因素。复杂度高的增删改查操作肯定会阻塞 Redis。

第一个阻塞点:集合全量查询和聚合操作

第二个阻塞点:bigkey 删除操作

第三个阻塞点:清空数据库

和磁盘交互时的阻塞点

因为磁盘 IO 一般都是比较费时费力,Redis 采用子进程方式生成RDB快照,以及执行 AOF 日志重写操作。

Redis 直接记录 AOF 日志时,会根据不同的写回策略对数据做落盘保存。(AOF日志的几个选项:always,同步落盘;everysec,每秒保存;No,数据保存在内存缓冲区,由操作系统决定何时写回)

第四个阻塞点:AOF 日志同步写。

主从节点交互时的阻塞点

在主从集群中,主库需要生成 RDB 文件,并传输给从库。库来接收了 RDB 文件后,需要使用 FLUSHDB 命令清空当前数据库,然后把 RDB 文件加载到内存。

第五个阻塞点:加载 RDB 文件

切片集群实例交互时的阻塞点

部署 Redis 切片集群时,每个 Redis 实例上分配的哈希槽信息需要在不同实例间进行传递,同时,当需要进行负载均衡或者有实例增删时,数据会在不同的实例间进行迁移。不过,哈希槽的信息量不大,而数据迁移是渐进式执行的,所以,一般来说,这两类操作对 Redis 主线程的阻塞风险不大。

如果你使用了 Redis Cluster 方案,而且同时正好迁移的是 bigkey 的话,就会造成主线程的阻塞,因为 Redis Cluster 使用了同步迁移。当没有 bigkey 时,切片集群的各实例在进行交互时不会阻塞主线程。

总结

Redis 实例五个阻塞点:

  • 集合全量查询和聚合操作;
  • bigkey 删除;
  • 清空数据库;
  • AOF 日志同步写;
  • 从库加载 RDB 文件。

阻塞点异步执行

集合全量查询和聚合操作从库加载 RDB 文件是没有办法异步执行操作。

第四个阻塞点“AOF 日志同步写”来说,为了保证数据可靠性,Redis 实例需要保证 AOF 日志中的操作记录已经落盘,这个操作虽然需要实例等待,但它并不会返回具体的数据结果给实例。所以,我们也可以启动一个子线程来执行 AOF 日志的同步写,而不用让主线程等待 AOF 日志的写完成。

删除操作并不需要给客户端返回具体的数据结果,删除key 引用关系使用后台子线程来异步执行删除操作也称为惰性删除(lazy free)。