问题

线上 redis 在排查慢查询时, 发现很多COMMAND 的 slowlog. 如下

image-20190823121956851

定位问题才发现, 是平时一些维护脚本, 通过 redis-cli 来访问数据, 然后 redis-cli 会自动发送 COMMAND 命令来获取命令数据来完善(因为有可能 redis-cli 版本跟 redis-server 版本不一致, 然后命令上有差别, 所以获取 server 的最新命令列表来完善)

这条命令会返回 redis-server 端的所有命令列表. 参见文档 command . 每次调用一次, 在一个繁忙的系统中挺耗时的,

原因

通过查看源码发现. 在 redis-cli.c 中搜索 "COMMAND" 可知

main -> cliIntegrateHelp() -> redisReply *reply = redisCommand(context, "COMMAND");

注 : 线上的 redis 版本为 3.2.4

并且是没有任何条件来判断不同的情况的, 也就是说, 所有用 redis-cli 成功之后, 都会尝试调用 COMMAND 来获取 redis-server 端的所有命令列表.

解决

目前暂时在源码里在 main 函数中注释掉 cliIntegrateHelp(); 的方法调用, 然后重新编译来使用, 以避免这种自动发送不需要, 但又挺耗时的 COMMAND 命令了.

新版本 redis

上面有问题的 redis 版本为 3.2.4

测试了下新版本 (4.0.14)的 redis 源码已经修改过了. 只有在交互模式下才会发送 COMMAND 命令.

main -> argc == 0 时 -> reply() -> cliIntegrateHelp() -> redisReply *reply = redisCommand(context, "COMMAND");

也就是说

# 下面这种并不会自动发送 COMMAND 命令了
redis-clie set hello world 

# 但这样子还是会自动发送 COMMAND . 进入交互模式
redis-cli
或
redis-cli -a pass