实测 MONITOR 的代价:一个及时读取的 MONITOR 客户端让管道 SET 吞吐从 740k 降到 485k 条/秒(-34%);不读取的 MONITOR 连接输出缓冲无上限(normal 0 0 0),100 万条命令后占 78 MB(约 78 字节/条);AUTH 参数被屏蔽,Lua 内命令标为 [0 lua]。
实测 redis-cli 的三个延迟工具:--latency 空闲时 avg 0.224 ms;制造 3 次 200 ms 阻塞后 max 203.995 ms 而 avg 只有 3.108 ms;--latency-history 让 150 ms 的尖峰只出现在它所在的窗口(max 151 ms);--intrinsic-latency 测本机自身调度抖动,不连接服务器。
用可加延迟的 TCP 代理模拟网络:RTT ≈ 0 时同步 38k、管道 1000 条 707k 条/秒;RTT 1 ms 时同步只有 566、管道 200k(354 倍);RTT 4 ms 时 161 vs 98k(611 倍);管道不是事务(另一个客户端能读到中间值),某条命令出错不影响其余。
量 Pipeline 批量大小:1 → 10 → 100 → 1000 → 2 万 → 10 万条的吞吐是 39k → 217k → 518k → 620k → 772k → 752k 条/秒(1000 以后趋平);一次发 100 万条 GET(1 KB)时服务器输出缓冲 914 MB,另一个客户端 PING 的最大停顿 7.3 ms。
用原始 socket 对比 RESP2 与 RESP3:HGETALL 从 *4 数组变成 %2 map、SMEMBERS 变成 ~ 集合、ZSCORE 变成 , 浮点、空回复从 $-1 变成 _;WITHSCORES 变成嵌套数组;100 字段 HGETALL 都是 2586 字节(类型信息变、大小不变);CLIENT TRACKING 时服务器主动推送 > 前缀的 invalidate 消息;HELLO 2/3 可在同一连接上切换。
用原始 socket 逐条验证 Redis 协议解析:multibulk 与 inline 两种请求格式;各种畸形请求的响应(invalid multibulk length、invalid bulk length、expected '$'、unbalanced quotes,回错误后断开;负长度与不完整请求则无回复、继续等待);client-query-buffer-limit 在 bulk 未收完时关闭连接;一条带 500 MB value 的 SET 往返 438 ms。
验证 Redis 的线程模型:默认进程有 4 个线程(主线程 + 3 个后台线程),io-threads 4 时 7 个;redis-benchmark 加压时 SET 吞吐在约 1341k 条/秒处趋平(16 个连接 1341k、64 个连接 1350k),同时 Redis 进程 CPU 100%——一个核被主线程占满。
验证 BIO 后台线程的作用:磁盘被大量 fsync 写入占满时,appendfsync everysec 的 SET p99 仍是 0.043 ms(无负载 0.043 ms),而 always 的 p99 从 4.6 ms 涨到 14.1 ms、最大 289 ms;UNLINK 大集合后 lazyfree_pending_objects = 1 持续约 100 ms 后被后台线程释放。
实测 Redis 8.10.2 的 Lazy Free:所有 lazyfree 配置默认 no;释放 200 万成员的集合,DEL 165 ms(另一个连接 PING 停顿 164 ms),UNLINK 0.7 ms;lazyfree-lazy-user-del yes 让 DEL 变异步;FLUSHALL 404 ms vs ASYNC 0.4 ms;大 key 过期时 lazyfree-lazy-expire no 造成 213 ms 停顿,yes 只有 0.5 ms。
实测 io-threads 1/2/4/8(本机 10 核,redis-benchmark 与 Redis 同机):INFO threads 证明读取被均分到 I/O 线程(io-threads 4 时主线程读 0 次、三个 I/O 线程各约 330 万次),但吞吐只提升约 5–12%(无管道 50 连接 89k → 95k;400 连接 93k → 105k;管道 16 1.33M → 1.50M)。
实测 hz 与 dynamic-hz:过期事件比 TTL 晚的中位数 hz 1 时 702 ms、hz 10 时 6.0 ms、hz 100 时 7.5 ms;空闲 CPU 10 秒 0.013 s(hz 10)/ 0.032 s(hz 100)/ 0.071 s(hz 500);dynamic-hz yes 时连接数到 4000 才把实际 hz 从 10 提到 20。
在 libc 分配器的 Redis 上演示内存碎片的来历:写入 100 万个 key 后随机删除 90%,used_memory 从 171 MB 降到 18 MB,used_memory_rss 却仍是 189 MB,mem_fragmentation_ratio 从 1.10 涨到 10.38;并如实记录:主动碎片整理(activedefrag)需要 jemalloc,本机构建不支持,CONFIG SET 直接报错。