bigywater.tech
Redis · 109

Redis io-threads

Redis 6 引入 I/O 多线程,常被说成「让 Redis 多线程了」。它到底做了什么、能带来多少吞吐提升?这篇在本机上用 redis-benchmark 量三种负载,并用 INFO threads 的计数证明 I/O 线程确实分担了读写;同时坦率地说明:在压测与被测同机的条件下,收益很有限。

主线程读 0 次
io-threads 4 时,INFO threads 显示 io_thread_0(主线程)读了 0 次,三个 I/O 线程各约 330 万次
+12% / +12%
本机测得的最大收益:400 连接无管道(io-threads 8)/ 管道 16(io-threads 4)
同机压测
redis-benchmark 与 Redis 抢同一批 CPU,结果偏保守

吞吐对比

每格 3 次取中位;redis-benchmark 8 个线程、GET、value 3 字节
实测 · 本机执行输出
io-threads        50 连接 无管道       400 连接 无管道      50 连接 管道 16
         1            89467            93406          1332741
         2            89451            94883          1199520
         4            93691            99463          1498127
         8            95117           104661          1498127

三种负载下 io-threads 从 1 到 8 的提升都不大:50 连接无管道 89k → 95k,400 连接无管道 93k → 105k,50 连接管道 16 1.33M → 1.50M(io-threads 8 与 4 相同,应是压测端上限)。io-threads 2 在管道 16 时反而低于 1(1.20M vs 1.33M),是单次测量的波动,我没有重复确认。

I/O 线程确实在干活

实测 · 本机执行输出
  io-threads 1: io_thread_0:clients=1,reads=10127521,writes=10126010
  io-threads 2: io_thread_0:clients=0,reads=0,writes=0  io_thread_1:clients=1,reads=10127521,writes=10126010
  io-threads 4: io_thread_0:clients=0,reads=0,writes=0  io_thread_1:clients=1,reads=3325621,writes=3325124  io_thread_2:clients=0,reads=3410113,writes=3409600  io_thread_3:clients=0,reads=3391787,writes=3391286
  io-threads 8: io_thread_0:clients=0,reads=0,writes=0  io_thread_1:clients=1,reads=1434808,writes=1434593  io_thread_2:clients=0,reads=1547269,writes=1547038  io_thread_3:clients=0,reads=1435633,writes=1435420  io_thread_4:clients=0,reads=1431821,writes=1431608  io_thread_5:clients=0,reads=1430638,writes=1430425  io_thread_6:clients=0,reads=1425922,writes=1425709  io_thread_7:clients=0,reads=1421430,writes=1421217

INFO 的 threads 段为每个线程列出处理的读/写次数。io-threads 1 时 io_thread_0(主线程)处理了全部读写;io-threads 4 时 io_thread_0 是 0,三个 I/O 线程各处理约三分之一;io-threads 8 时七个 I/O 线程平分。所以网络读写确实被挪出了主线程。

为什么在这里看不到大收益

命令的执行仍是单线程(第 106 篇)。I/O 线程只在「网络读写占了主线程大部分时间」时才有明显收益:多连接、大 value、真实网卡的场景。而这次测量里压测端与 Redis 在同一台机器上,抢同样的 CPU,压测端自己往往先到上限(管道 16 时 io-threads 4 与 8 得到完全相同的数字就是迹象)。这里没有独立的压测机,也没有更大的 value(我最初还试过 4 KB,收益同样不明显,没有整理进表里),所以不能据此说 I/O 线程没用,只能说在这个条件下提升有限。

分步演示:io-threads 的作用

Redis io-threads
本步的数据

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。本机 10 个核(6 个性能核);redis-benchmark -t get --threads 8;io-threads 由配置文件设置
    • 没有验证:独立压测机、真实网卡、更大的 value、io-threads-do-reads 等相关参数、Linux 上的表现、CPU 亲和性
    京ICP备2026067502号-1京公网安备11010502063487号