bigywater.tech
Redis · 107

Redis BIO 后台线程

Redis 的主线程不想等任何慢的系统调用,所以把其中几类交给后台线程(BIO):AOF 的 fsync、大对象的内存释放、文件的关闭/删除。这篇不数线程,而是用行为来验证:制造磁盘拥塞,看 fsync 在主线程上和在后台线程上的延迟有多大差别;再看后台释放大对象时的计数器。

0.043 ms
磁盘拥塞时 everysec 的 SET p99(无负载 0.043 ms)——fsync 在后台线程
14 ms / 289 ms
同样的磁盘拥塞下 always 的 p99 / 最大延迟——fsync 在请求路径上
pending 1 → 0
UNLINK 大集合后 lazyfree_pending_objects 的变化(约 100 ms)

fsync:后台 vs 请求路径

一个进程持续写 4 MB 块并 fsync,占满磁盘;Redis 端单客户端同步 SET 8 秒
实测 · 本机执行输出
appendfsync 磁盘负载          条数   p50 ms   p99 ms  p99.9 ms   max ms  aof_delayed_fsync
everysec   无         274496    0.028    0.043      0.08      1.9                  0
everysec   有         294232    0.027    0.043      0.08     14.2                  0
always     无           2800    2.989    4.607      9.20     10.8                  0
always     有           2064    2.591   14.118     32.78    288.8                  0

appendfsync everysec 下,fsync 由后台线程每秒做一次:磁盘拥塞时请求延迟的 p50/p99 几乎不变(p99 0.043 → 0.043 ms),最大值有偶发的毫秒级尖峰(14.2 ms)。appendfsync always 下,fsync 在请求路径上:无负载已经是 p50 3.0 ms,磁盘拥塞时 p99 14.1 ms、最大 289 ms。(磁盘拥塞是我用另一个进程的持续 fsync 制造的,macOS + SSD;不同磁盘上的绝对数字会不同。)

everysec 也不是永远安全:按文档的说法,如果一次 fsync 耗时过长(约 2 秒),主线程会被迫等待并增加 aof_delayed_fsync——这次实验里它始终是 0,没有触发,所以这一点没有验证。

lazy free:后台释放

实测 · 本机执行输出
  UNLINK 之后每 ~20 ms 采样 (lazyfree_pending_objects, lazyfreed_objects): [('1', '0'), ('1', '0'), ('1', '0'), ('1', '0'), ('1', '0'), ('0', '1')]

UNLINK 一个 200 万成员的集合:主线程只把 key 摘下并交给后台线程,INFO memory 的 lazyfree_pending_objects 显示 1 个待释放对象,大约 100 ms 后归 0、lazyfreed_objects 加 1。lazy free 各开关的效果见第 108 篇。

这次没有验证的部分

BIO 还有一类任务是「关闭/删除大文件」(比如 AOF 重写完成后删除旧文件),我没有找到办法在这台机器上单独观察它;线程的名字与具体数量在 macOS 上也看不到(第 106 篇只数出了线程总数)。所以这里说的三类任务里,fsync 与 lazy free 是我用行为验证的,文件关闭是按 Redis 文档转述的。

分步演示:BIO 帮主线程挡住了什么

Redis BIO 后台线程
本步的数据

    本文用到的工具与边界

    • 本机 macOS 27 / Redis 8.10.2 独立实例(本机回环端口,save 关闭),redis-cli 风格输出由自写的 RESP 客户端打印;计时用 time.perf_counter,数字每次运行会有小幅抖动。磁盘拥塞由另一个 Python 进程的连续 4 MB 写 + fsync 制造;每种配置 8 秒;macOS + SSD
    • 没有验证:Linux 上 fsync 的行为差异、BIO 线程的具体数量与名字、文件关闭任务、磁盘更慢时 everysec 触发 aof_delayed_fsync 的情形
    京ICP备2026067502号-1京公网安备11010502063487号