Redis为什么这么快

Redis为什么这么快?

原因

  1. Redis基于内存的数据存储,内存的读写速度远高于硬盘
  2. Redis提供了高效的数据结构
  3. Redis使用了单线程模型处理命令执行,避免了多线程上下文切换开销、以及资源同步开销
  4. Redis采用了高效的IO多路复用模型
  5. Redis 客户端和服务端之间使用 RESP (Redis Serialization Protocol) 协议通信

为什么要用单线程?多线程难道不会更快吗?

  1. 在Redis这个数据库相关的场景下,CPU不是瓶颈,内存和IO才是(后续为了解决网络数据IO的性能瓶颈,在网络IO操作使用了多线程),单线程已经足够胜任。redis相关的IO操作:
    • 磁盘IO:如持久化机制,使用后台子进程解决
    • 网络IO:redis6.0后使用多线程处理
  2. 单线程能够避免多线程场景下的锁机制、线程切换的开销
  3. 单线程能够简化问题

Redis6.0引入了多线程

Redis 6.0 引入了多线程 I/O。这并不是说 Redis 变成了多线程数据库,而是指:

  • 命令执行(读写内存数据)依然是 单线程 的(保证原子性,无需锁)。
  • 网络数据读写(Socket Read/Write)变成了 多线程 处理。
  • 原因: 随着网卡速度越来越快,解析网络请求包成了瓶颈。多线程 I/O 旨在解决网络带宽处理能力的瓶颈,进一步提升吞吐量。

IO多路复用和多线程IO

  • IO 多路复用 解决的是 “同时监听大量连接” 的问题(解决连接数并发)。
  • 多线程 IO 解决的是 “快速读写网络数据” 的问题(解决数据吞吐量)。

它们的关系:如何协作?

在 Redis 6.0 之前,Redis 是“单线程”的,意味着监听连接读写网络数据都是同一个人(主线程)。 在 Redis 6.0 之后,Redis 引入了多线程 IO,它们开始分工合作。

  1. 监听 (IO 多路复用): 主线程通过 epoll 监听所有连接。发现连接 A 有数据发过来了!
  2. 读取 (多线程 IO): 主线程把连接 A 分配给IO 线程组。IO 线程并行地把数据从 Socket 读出来,并解析好命令。
    • (注:此时主线程会等待 IO 线程组全部干完活)
  3. 执行 (主线程 - 依然单线程): 数据都读好、解析好了。主线程拿过来,执行 SET key value
    • (注:执行命令依然是排队单线程执行,不需要加锁,保证原子性)
  4. 发送 (多线程 IO): 执行完了,要返回 “OK”。主线程把结果打包好,再次分配给IO 线程组,让它们并行地把数据写回 Socket 发送给客户端。
组件 线程归属 职责
IO 多路复用 (epoll_wait) 主线程 负责“站岗放哨”。它监听所有连接,一旦发现有数据来了(可读)或者可以发数据了(可写),就通知下一步。
IO 线程 (Worker Threads) 辅助线程组 负责“搬运重活”。它们只负责从 Socket 读取/解析数据,或者把响应数据 写回 Socket。它们负责监听。
命令执行 (Command Exec) 主线程 负责“核心业务”。执行 GET, SET 等逻辑,修改内存数据。

为什么要有这种变化?

您可能会问:“以前没有多线程 IO,Redis 不也很快吗?”

是的,但瓶颈变了。

  • 早期: 瓶颈是内存CPU。单线程足以应付网络流量,因为以前是千兆网卡。
  • 现在: 瓶颈变成了网络带宽。现在的服务器动辄万兆网卡,每秒钟能进来的数据包太多了。
    • 如果还是单线程,主线程光是把这么巨大的数据从 Socket 读到内存里,CPU 就已经累趴下了,根本没时间去执行命令。
    • 所以,引入多线程 IO 就是为了把“读写数据”这个消耗 CPU 的体力活分摊出去,让主线程专注于“执行命令”这个核心脑力活。

Redis为什么这么快
http://example.com/2025/12/14/Redis为什么这么快/
作者
Kon4tsu
发布于
2025年12月14日
许可协议