char *section = c->argc == 2 ? c->argv[1]->ptr : "default";
//设定具体取什么样的信息
//自定义检查点: 1 2 3
if (c->argc > 2)
{
addReply(c,shared.syntaxerr);
return;
}
//如果参数过多,则返回 "-ERR syntax error\r\n"
//自定义检查点: 1 2 3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
重点在于函数:genRedisInfoString
下面开始分析函数:genRedisInfoString
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sds info = sdsempty();
//""
//自定义检查点: 1 2 3
time_t uptime = server.unixtime-server.stat_starttime;
//已经过去的时间
自定义检查点: 1 2 3
int j;
int numcommands;
//定义两个整型变量
//自定义检查点: 1 2 3
struct rusage self_ru;
struct rusage c_ru;
unsigned long lol, bib;
int allsections = 0;
//指示:是否要复制所有的
int defsections = 0;
//指示:是否要复制default
int sections = 0;
//设定若干变量
//自定义检查点: 1 2 3
if (section)
{
allsections = strcasecmp(section,"all") == 0;
defsections = strcasecmp(section,"default") == 0;
}
//自定义检查点: 1 2 3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
getrusage(RUSAGE_SELF, &self_ru);
//获取当前进程信息
getrusage(RUSAGE_CHILDREN, &c_ru);
//获取子进程信息
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
getClientsMaxBuffers函数调用了listRewind函数,
listRewind函数是干嘛的???
代码是:
li->next = list->head;
li->direction = AL_START_HEAD;
这个就不用我多说了吧,增加了一个头节点。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面用了listNext函数,从字面上理解为取出下一个节点,
listNode *listNext(listIter *iter)
{
//自定义检查点: 1 2 3
listNode *current = iter->next;
//取出当前的下一个节点
//自定义检查点: 1 2 3
if (current != NULL)
{
if (iter->direction == AL_START_HEAD)
iter->next = current->next;
else
iter->next = current->prev;
}
//及时更新iter->next;
return current;
//返回当前值
//自定义检查点: 1 2 3
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
返回到getClientsMaxBuffers函数
c = listNodeValue(ln);
通过查看代码及以前的记录,发现c指向某个redisClient的指针,也就是说,
做了这么多工作,就是为了取出一个redisClient指针。
有了指针,巧妇何愁有米之炊!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unsigned long lol = 0;
//设置为redisClient->reply的长度,最后是各个redisClient中最长的
unsigned long bib = 0;
//设置为redisClient->querybuf的数据长度,最后是各个redisClient中最长的
getClientsMaxBuffers函数结束了,结束后
lol,bib分别指向server.clients中的client的最大输出和输入长度。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
剩下的分别是若干各方面信息,我觉得没有把redis全部看完,对这些数据也不会有特别深刻的理解。
我估计redis的作者也是边写软件边添加统计信息的代码。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Server */
if (allsections || defsections || !strcasecmp(section,"server"))
{
struct utsname name;
char *mode;
if (server.sentinel_mode) mode = "sentinel";
else mode = "standalone";
if (sections++) info = sdscat(info,"\r\n");
uname(&name);
info = sdscatprintf(info,
"# Server\r\n"
"redis_version:%s\r\n"
"redis_git_sha1:%s\r\n"
"redis_git_dirty:%d\r\n"
"redis_build_id:%llx\r\n"
"redis_mode:%s\r\n"
"os:%s %s %s\r\n"
"arch_bits:%d\r\n"
"multiplexing_api:%s\r\n"
"gcc_version:%d.%d.%d\r\n"
"process_id:%ld\r\n"
"run_id:%s\r\n"
"tcp_port:%d\r\n"
"uptime_in_seconds:%jd\r\n"
"uptime_in_days:%jd\r\n"
"hz:%d\r\n"
"lru_clock:%ld\r\n"
"config_file:%s\r\n",
REDIS_VERSION,
redisGitSHA1(),
strtol(redisGitDirty(),NULL,10) > 0,
(unsigned long long) redisBuildId(),
mode,
name.sysname, name.release, name.machine,
server.arch_bits,
aeGetApiName(),
#ifdef __GNUC__
__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__,
#else
0,0,0,
#endif
(long) getpid(),
server.runid,
server.port,
(intmax_t)uptime,
(intmax_t)(uptime/(3600*24)),
server.hz,
(unsigned long) server.lruclock,
server.configfile ? server.configfile : "");
}
服务器的信息
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Clients */
if (allsections || defsections || !strcasecmp(section,"clients"))
{
if (sections++) info = sdscat(info,"\r\n");
info = sdscatprintf(info,
"# Clients\r\n"
"connected_clients:%lu\r\n"
"client_longest_output_list:%lu\r\n"
"client_biggest_input_buf:%lu\r\n"
"blocked_clients:%d\r\n",
listLength(server.clients)-listLength(server.slaves),
lol, bib,
server.bpop_blocked_clients);
}
客户端的信息
~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Memory */
if (allsections || defsections || !strcasecmp(section,"memory"))
{
char hmem[64];
char peak_hmem[64];
bytesToHuman(hmem,zmalloc_used_memory());
bytesToHuman(peak_hmem,server.stat_peak_memory);
if (sections++) info = sdscat(info,"\r\n");
info = sdscatprintf(info,
"# Memory\r\n"
"used_memory:%zu\r\n"
"used_memory_human:%s\r\n"
"used_memory_rss:%zu\r\n"
"used_memory_peak:%zu\r\n"
"used_memory_peak_human:%s\r\n"
"used_memory_lua:%lld\r\n"
"mem_fragmentation_ratio:%.2f\r\n"
"mem_allocator:%s\r\n",
zmalloc_used_memory(),
hmem,
zmalloc_get_rss(),
server.stat_peak_memory,
peak_hmem,
((long long)lua_gc(server.lua,LUA_GCCOUNT,0))*1024LL,
zmalloc_get_fragmentation_ratio(),
ZMALLOC_LIB
);
}
//自定义检查点: 1 2 3
剩下的代码就不多说了,没啥好说的,就是信息统计。