博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis源码笔记 - slowlog
阅读量:6161 次
发布时间:2019-06-21

本文共 5202 字,大约阅读时间需要 17 分钟。

slowlog是redis提供的进行query分析的工具。它将执行时间长的命令统一以list形式保存在内存之中,使用者可以通过slowlog命令查看这些慢query,从而分析系统瓶颈。

最好的分析笔记是作者的注释,除此之外,会做简要记录。

slowlog.h

1 /* This structure defines an entry inside the slow log list */ 2 typedef struct slowlogEntry { 3     robj **argv;                      //记录query参数 4     int argc; 5     long long id;       /* Unique entry identifier. */ 6     long long duration; /* Time spent by the query, in nanoseconds. */ 7     time_t time;        /* Unix time at which the query was executed. */ 8 } slowlogEntry; 9 10 /* Exported API */11 void slowlogInit(void);               //在redis.c的initServer函数中被调用,初始化一个list结构,只在系统启动时调用一次12 void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration);13 14 /* Exported commands */15 void slowlogCommand(redisClient *c);  //slowlog Command将会触发此函数被调用

slowlog.c

1 #include "redis.h"  2 #include "slowlog.h"  3   4 /* Slowlog implements a system that is able to remember the latest N  5  * queries that took more than M microseconds to execute.  6  *  7  * The execution time to reach to be logged in the slow log is set  8  * using the 'slowlog-log-slower-than' config directive, that is also  9  * readable and writable using the CONFIG SET/GET command. 10  * 11  * The slow queries log is actually not "logged" in the Redis log file     //只在内存中保存 12  * but is accessible thanks to the SLOWLOG command. */ 13  14 /* Create a new slowlog entry. 15  * Incrementing the ref count of all the objects retained is up to 16  * this function. */ 17 slowlogEntry *slowlogCreateEntry(robj **argv, int argc, long long duration) { 18     slowlogEntry *se = zmalloc(sizeof(*se)); 19     int j; 20  21     se->argc = argc; 22     se->argv = zmalloc(sizeof(robj*)*argc); 23     for (j = 0; j < argc; j++) { 24         se->argv[j] = argv[j]; 25         incrRefCount(argv[j]); 26     } 27     se->time = time(NULL); 28     se->duration = duration; 29     se->id = server.slowlog_entry_id++; 30     return se; 31 } 32  33 /* Free a slow log entry. The argument is void so that the prototype of this 34  * function matches the one of the 'free' method of adlist.c. 35  * 36  * This function will take care to release all the retained object. */ 37 void slowlogFreeEntry(void *septr) { 38     slowlogEntry *se = septr; 39     int j; 40  41     for (j = 0; j < se->argc; j++) 42         decrRefCount(se->argv[j]); 43     zfree(se->argv); 44     zfree(se); 45 } 46  47 /* Initialize the slow log. This function should be called a single time 48  * at server startup. */ 49 void slowlogInit(void) { 50     server.slowlog = listCreate(); 51     server.slowlog_entry_id = 0; 52     listSetFreeMethod(server.slowlog,slowlogFreeEntry); 53 } 54  55 /* Push a new entry into the slow log. 56  * This function will make sure to trim the slow log accordingly to the 57  * configured max length. */ 58 void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration) { 59     if (server.slowlog_log_slower_than < 0) return; /* Slowlog disabled */ 60     if (duration >= server.slowlog_log_slower_than) 61         listAddNodeHead(server.slowlog,slowlogCreateEntry(argv,argc,duration)); 62  63     /* Remove old entries if needed. */ 64     while (listLength(server.slowlog) > server.slowlog_max_len) 65         listDelNode(server.slowlog,listLast(server.slowlog)); 66 }  //该函数在每次命令执行时均被调用,对于非慢速的命令,只有一个分支调用的开销; 67  68 /* Remove all the entries from the current slow log. */ 69 void slowlogReset(void) { 70     while (listLength(server.slowlog) > 0) 71         listDelNode(server.slowlog,listLast(server.slowlog)); 72 } 73  74 /* The SLOWLOG command. Implements all the subcommands needed to handle the 75  * Redis slow log. */ slow long get (count) || slowlog reset || slowlog len 76 void slowlogCommand(redisClient *c) { 77     if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"reset")) { 78         slowlogReset(); 79         addReply(c,shared.ok); 80     } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"len")) { 81         addReplyLongLong(c,listLength(server.slowlog)); 82     } else if ((c->argc == 2 || c->argc == 3) && 83                !strcasecmp(c->argv[1]->ptr,"get")) 84     { 85         long count = 10, sent = 0; 86         listIter li; 87         void *totentries; 88         listNode *ln; 89         slowlogEntry *se; 90  91         if (c->argc == 3 && 92             getLongFromObjectOrReply(c,c->argv[2],&count,NULL) != REDIS_OK) 93             return; 94  95         listRewind(server.slowlog,&li); 96         totentries = addDeferredMultiBulkLength(c); 97         while(count-- && (ln = listNext(&li))) { 98             int j; 99 100             se = ln->value;101             addReplyMultiBulkLen(c,4);102             addReplyLongLong(c,se->id);103             addReplyLongLong(c,se->time);104             addReplyLongLong(c,se->duration);105             addReplyMultiBulkLen(c,se->argc);106             for (j = 0; j < se->argc; j++)107                 addReplyBulk(c,se->argv[j]);     //返回的消息是一个类似嵌套的结构108             sent++;109         }110         setDeferredMultiBulkLength(c,totentries,sent);111     } else {112         addReplyError(c,113             "Unknown SLOWLOG subcommand or wrong # of args. Try GET, RESET, LEN.");114     }115 }

转载地址:http://wsefa.baihongyu.com/

你可能感兴趣的文章
循环的控制命令介绍
查看>>
记今日访问网页总是报nginx 403的解决
查看>>
内置函数
查看>>
linux:记录一次 处理tomcat启动卡死无报错现象的曲折过程
查看>>
centos7 安装vsftpd和配置以及虚拟用户权限分配
查看>>
MVC的基类
查看>>
修炼职场
查看>>
form表单file,select选择后自动提交
查看>>
正则表达式之分组
查看>>
中国硬科技城市发展指数正式发布,西安跻身前十
查看>>
nginx 负载均衡proxy 配置
查看>>
linux下rsync+sersync实现自动备份数据
查看>>
LVS-模式
查看>>
Linux 密码复杂度
查看>>
ArchLinux安装简单安装教程
查看>>
#9 shell脚本的函数运用
查看>>
input文本框不可编辑的方法
查看>>
weblogic-修改控制台登录密码
查看>>
云无边界,阿里云混合云数据同步发布
查看>>
Codeigniter开发技巧:连接多个数据库(可实现DB读写分离)
查看>>