Redis(三):SLOW LOG源码简析

目录

  • Slowlog概述
  • Slowlog源码简析
  • Slowlog测试

Slowlog概述 
  
slowlog是指那些执行时间超过某个指定时间的查询,这里的执行时间不包括对磁盘的I/O操作、与客户端的连接等额外开销,只包含对内存数据的操作时间。Redis提供了以下两个配置来管理slowlog 

# 超时时间阈值设定,单位微妙
slowlog-log-slower-than 10000

# 可存储的慢日志条数
slowlog-max-len 128

 slowlog-log-slower-than用于指定超时时间的阈值,超过该值的操作会被认为是慢查询,Redis会为其生成一条对应的慢日志存储在内存中。同时为了防止慢日志占用过多内存空间,通过slowlog-max-len可以限定内存中可存储的慢日志的最大条数,当超出最大条数后,根据FIFO规则,会将最早的slowlog删除。

Slowlog源码简析
  slowlog.h定义了慢日志对应的结构体信息

#define SLOWLOG_ENTRY_MAX_ARGC 32    /* 每条慢查询日志最多记录32个查询参数 */
#define SLOWLOG_ENTRY_MAX_STRING 128 /* 每个查询参数最长只记录128个字符 */

/* This structure defines an entry inside the slow log list */
typedef struct slowlogEntry {
    robj **argv;        /* 参数信息 */
    int argc;           /* 参数个数 */
    long long id;       /* 日志ID: Unique entry identifier. */   
    long long duration; /* 命令执行时间: Time spent by the query, in microseconds. */
    time_t time;        /* 日志创建时间:Unix time at which the query was executed. */
} slowlogEntry;

/* Exported API */
void slowlogInit(void);
void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration);

/* Exported commands */
void slowlogCommand(client *c);

 slowlog.c中定义了具体的流程,以下是部分源码

/* Initialize the slow log. This function should be called a single time
 * at server startup. */
void slowlogInit(void) {
    server.slowlog = listCreate();    /* 创建一个list列表 */
    server.slowlog_entry_id = 0;      /* 日志ID从0开始 */
    listSetFreeMethod(server.slowlog,slowlogFreeEntry);  /* 指定慢查询日志list空间的释放方法 */
}

/* Push a new entry into the slow log.
 * This function will make sure to trim the slow log accordingly to the
 * configured max length. */
void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration) {
    if (server.slowlog_log_slower_than < 0) return; /* Slowlog disabled */ /* 负数表示禁用 */
    if (duration >= server.slowlog_log_slower_than) /* 如果执行时间 > 指定阈值*/
        listAddNodeHead(server.slowlog,slowlogCreateEntry(argv,argc,duration)); /* 创建一个slowlogEntry对象,添加到列表首部*/

    /* Remove old entries if needed. */
    while (listLength(server.slowlog) > server.slowlog_max_len) /* 如果列表长度 > 指定长度 */
        listDelNode(server.slowlog,listLast(server.slowlog));  /* 移除列表尾部元素 */
}

Slowlog测试
   step1:
为了方便测试,这里临时设置时间阈值为1微妙,长度限制为3条。任意执行几条命令,比如mset、keys *、slowlog get等

  从结果可以看出,有三条命令执行时间都超过了1微妙,都生成了对应的slowlog。而且slowlog get打印输出的信息和slowlogEntry结构体相对应。
  对于命令01config set...由于其执行时间<10ms(在执行命令02之前时间阈值为10ms),所以没有生成慢日志。对于命令5slowlog get,其执行时间其实是超过了1纳秒的,之所以没有打印出来,是因为slowlog get在返回给客户端信息之后才会生成慢日志并存储进内存。step2验证了这一点
  step2:继续执行任意命令,比如一个sadd,然后再执行slowlog get。
  结果说明ID等于0和1的慢日志已经被删除;对于key长度>128的,在记录日志时进行了截取;代表上次slowlog get命令的慢日志被打印出来了。

Slowlog应用

  • 慢查询时间阈值默认为10ms,依官方介绍来看10毫秒确实算慢了,生产环境中可以适当的调低该值,比如1~5毫秒。

  • 由于慢查询日志列表的FIFO规则,为了防止日志丢失的情况,生产环境中可以定期执行 slowlog get命令将慢查询日志持久化到文件或DB中,然后通过可视化工具进行查询。同时为了防止在高并发情况下慢日志数量瞬间达到规定上限,在尚未持久化就已经丢失的情况,可以调大slow-max-len,比如1000。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值