MONITOR 是调试利器,也是生产事故的常见来源。这篇量它的两笔代价:吞吐下降多少,以及一个「忘了关的、不读取的」MONITOR 连接会让服务器内存涨到多大。
没有 MONITOR:740k 条/秒 有一个及时读取的 MONITOR 客户端:485k 条/秒(降低 34%)
管道 SET 20 万条,每种情形测 3 次取中位:没有 MONITOR 740k/s,有一个及时读取的 redis-cli monitor 485k/s。这是本机、每条命令很小、单个监控客户端下的数字;命令越多、参数越大,代价越明显。
CONFIG GET client-output-buffer-limit → normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60 已执行 200000 条命令:used_memory 比开始时多 15.1 MB,该 MONITOR 连接的 omem = 15.1 MB 已执行 400000 条命令:used_memory 比开始时多 30.8 MB,该 MONITOR 连接的 omem = 30.8 MB 已执行 600000 条命令:used_memory 比开始时多 46.6 MB,该 MONITOR 连接的 omem = 46.5 MB 已执行 800000 条命令:used_memory 比开始时多 62.3 MB,该 MONITOR 连接的 omem = 62.3 MB 已执行 1000000 条命令:used_memory 比开始时多 78.0 MB,该 MONITOR 连接的 omem = 78.0 MB 关闭这个连接后 used_memory 比开始多 0.0 MB
我让一个 MONITOR 连接不读取(并把它的接收缓冲调到 4 KB)。CONFIG GET client-output-buffer-limit 里 normal 是 0 0 0——MONITOR 客户端属于 normal 类,没有上限。20 万条命令后它的 omem 是 15 MB,之后线性增长到 100 万条时 78 MB,约 78 字节/条。关掉连接后 used_memory 立刻回到起点。
OK
1790706215.568948 [0 127.0.0.1:58177] "SET" "hello" "world"
1790706215.569257 [0 127.0.0.1:58177] "GET" "hello"
1790706215.569632 [0 127.0.0.1:58177] "AUTH" "(redacted)" "(redacted)"
1790706215.569896 [0 127.0.0.1:58177] "EVAL" "return redis.call('INCR','n')" "0"
1790706215.570026 [0 lua] "INCR" "n"每条命令一行,带微秒时间戳、数据库号和客户端地址。AUTH 的参数被替换为 (redacted);Lua 脚本里的命令显示为 [0 lua]。其它命令的参数(包括业务数据)原样出现,所以 MONITOR 本身也是一个信息泄露面。