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

本文共 5269 字,大约阅读时间需要 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 }

转载于:https://www.cnblogs.com/liuhao/archive/2012/05/20/2510725.html

你可能感兴趣的文章
python3 序列分片记录
查看>>
Atitit.git的存储结构and 追踪
查看>>
atitit 读书与获取知识资料的attilax的总结.docx
查看>>
B站 React教程笔记day2(3)React-Redux
查看>>
找了一个api管理工具
查看>>
Part 2 - Fundamentals(4-10)
查看>>
使用Postmark测试后端存储性能
查看>>
NSTextView 文字链接的定制化
查看>>
第五天站立会议内容
查看>>
ATMEGA16 IOport相关汇总
查看>>
JAVA基础-多线程
查看>>
面试题5:字符串替换空格
查看>>
[Codevs] 线段树练习5
查看>>
Amazon
查看>>
component-based scene model
查看>>
Echart输出图形
查看>>
hMailServer搭建简单邮件系统
查看>>
从零开始学习jQuery
查看>>
Spring+SpringMVC+MyBatis深入学习及搭建(四)——MyBatis输入映射与输出映射
查看>>
opacity半透明兼容ie8。。。。ie8半透明
查看>>