说明 简单来说,slowlog 是 Redis 专门记录“慢查询”的日志模块。它只关注命令本身的实际执行时长,不包含客户端网络传输、回复发送等 IO 开销——换句话说,记录的是从命令开始执行到执行完毕的纯运算耗时。 很贴心的一点是,slowlog 的数据直接保存在内存中,读写速度极快。因此,即使频繁
简单来说,slowlog 是 Redis 专门记录“慢查询”的日志模块。它只关注命令本身的实际执行时长,不包含客户端网络传输、回复发送等 IO 开销——换句话说,记录的是从命令开始执行到执行完毕的纯运算耗时。

长期稳定更新的攒劲资源: >>>点此立即查看<<<
很贴心的一点是,slowlog 的数据直接保存在内存中,读写速度极快。因此,即使频繁查询慢日志,也不会对 Redis 性能造成明显影响。
slowlog 的配置主要围绕两个参数:
配置方式有两种:
slowlog-log-slower-than 和 slowlog-max-len 参数,重启后生效。CONFIG SET 命令动态调整,例如 CONFIG SET slowlog-log-slower-than 20000,即时生效,无需重启。与 slowlog 相关的操作命令很简洁:
底层实现上,slowlog 采用一个链表(list)来存储日志条目。当一条命令执行完毕后,Redis 会调用 call() 函数,其中有一个关键判断:如果当前不是在加载 AOF 的上下文中,并且客户端没有被阻塞,就调用 slowlogPushCurrentCommand() 决定是否将这条命令写入慢日志。
核心代码如下:
void call(client *c, int flags) {
//如果当前在 AOF 加载上下文,不要写 slowlog / latency / INFO stats
int update_command_stats = !isAOFLoadingContext();
//......
if (update_command_stats && !(c->flags & CLIENT_BLOCKED))
slowlogPushCurrentCommand(c, real_cmd, c->duration);
//......
}
void slowlogPushCurrentCommand(client *c, struct redisCommand *cmd, ustime_t duration) {
//是否需要纪录slowlog
if (cmd->flags & CMD_SKIP_SLOWLOG)
return;
robj **argv = c->original_argv ? c->original_argv : c->argv;
int argc = c->original_argv ? c->original_argc : c->argc;
slowlogPushEntryIfNeeded(c,argv,argc,duration);
}
真正写入链表的逻辑在 slowlogPushEntryIfNeeded() 函数中:
void slowlogPushEntryIfNeeded(client *c, robj **argv, int argc, long long duration) {
//判断slowlog_log_slower_than配置是否小于0,是否记录日志
if (server.slowlog_log_slower_than < 0) return; /* Slowlog disabled */
//如果执行时间大于slowlog_log_slower_than时间 追加到slow log list头部中
if (duration >= server.slowlog_log_slower_than)
listAddNodeHead(server.slowlog,
slowlogCreateEntry(c,argv,argc,duration));
//判断slow log list长度是否大于slowlog_max_len,
//如果大于slowlog_max_len 删除list尾部元素
/* Remove old entries if needed. */
while (listLength(server.slowlog) > server.slowlog_max_len)
listDelNode(server.slowlog,listLast(server.slowlog));
}
流程很清晰:首先检查 slowlog_log_slower_than 是否被设为负数(负数表示禁用慢日志);如果未禁用,且命令执行时间大于等于阈值,就在链表头部插入一条新日志;最后检查链表长度是否超过 slowlog_max_len,如果超了,就反复从尾部删除最旧的记录,直到长度符合上限。
这种设计让读写都很快——插入在头部,删除在尾部,都是 O(1) 操作。由于日志存储在内存中,获取慢日志时无需磁盘 IO,非常适合在线排查性能问题。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述