强子哥哥

Redis源码分析系列十七:processCommand后续

孤人 提交于 2019-12-28 18:07:54
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 继续研究。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ((dictSize(c->pubsub_channels) > 0 || listLength(c->pubsub_patterns) > 0) && c->cmd->proc != subscribeCommand && c->cmd->proc != unsubscribeCommand && c->cmd->proc != psubscribeCommand && c->cmd->proc != punsubscribeCommand) { addReplyError(c,"only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context"); return REDIS_OK; } 在某些状态下,只能使用这几种命令。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* Only allow INFO and SLAVEOF when slave-serve-stale-data is no and * we are a slave with a broken link with master. */ if

Redis源码分析系列十六:processCommand研究

时光毁灭记忆、已成空白 提交于 2019-12-28 18:04:12
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 现在让我们回到processInputBuffer函数。 剩下的代码是: /* Multibulk processing could see a <= 0 length. */ if (c->argc == 0) { resetClient(c); } else { /* Only reset the client when the command was executed. */ if (processCommand(c) == REDIS_OK) resetClient(c); } 假设我们已经取到了一些命令,那么c->argc则大于0 那就会执行processCommand函数。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* The QUIT command is handled separately. Normal command procs will * go through checking for replication and QUIT will cause trouble * when FORCE_REPLICATION is enabled and would be implemented in * a regular

Redis源码分析系列十八:1 命令"auth"---authCommand

痞子三分冷 提交于 2019-12-28 17:50:30
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 这个命令主要是密码验证信息,我们来看如何处理的,执行函数为authCommand。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 代码如下: void authCommand(redisClient *c) { if (!server.requirepass) { addReplyError(c,"Client sent AUTH, but no password is set"); } else if (!time_independent_strcmp(c->argv[1]->ptr, server.requirepass)) { c->authenticated = 1; addReply(c,shared.ok); } else { c->authenticated = 0; addReplyError(c,"invalid password"); } } 看起来代码不多,我们细细研究。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 首先,我之前的文章为了简单,没有修改配置文件,导致redis是不需要密码验证的, 因为redis.conf配置文件里有一行是: # requirepass foobared 那么为了密码验证如何做

Redis源码分析系列六:initserver中

微笑、不失礼 提交于 2019-11-30 04:43:51
server.db = zmalloc(sizeof(redisDb)*server.dbnum); //开辟缓冲区 listenToPort(server.port,server.ipfd,&server.ipfd_count); 显然这个函数是监听端口 跟踪这个函数,进入,发现最终是掉用_anetTcpServer函数。 下面是_anetTcpServer函数的解析。 static int _anetTcpServer(char *err, int port, char *bindaddr, int af) { int s, rv; char _port[6]; /* strlen("65535") */ //监听端口 struct addrinfo hints; //.ai_family = AF_INET; //.ai_socktype = SOCK_STREAM; //.ai_flags = AI_PASSIVE; struct addrinfo *servinfo; struct addrinfo *p; snprintf(_port,6,"%d",port); memset(&hints,0,sizeof(hints)); hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; hints.ai_flags =

Redis源码分析系列五:initServer上

旧街凉风 提交于 2019-11-30 04:43:29
刚下班,吃了点饭,精神饱满,让我们继续分析initServer,这个函数还是很重要的。 ~~~~~~~~~~~~~~~~~~ int j; signal(SIGHUP, SIG_IGN);//注册信号处理程序为忽略 signal(SIGPIPE, SIG_IGN);//注册信号处理程序为忽略 下面是setupSignalHandlers();函数,看这个函数的代码,得知目的是: 为信号SIGTERM注册处理程序sigtermHandler 为信号SIGSEGV,SIGBUS,SIGFPE,SIGILL统一注册信号处理程序:sigsegvHandler /////////////////////////////////////////////////////////////////////////////// if (server.syslog_enabled) { openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT, server.syslog_facility); } //默认不执行 server.current_client = NULL;//设置current_client--->NULL server.clients = listCreate(); //初始化clients server

Redis源码分析系列七:initServer下

[亡魂溺海] 提交于 2019-11-29 03:40:32
这个函数快到尾声了,一鼓作气! if(aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR) { redisPanic("Can't create the serverCron time event."); exit(1); } 这个函数是创建时间事件。 这样的话,server->el的timeEventHead就链接了一个成员如下: /* typedef struct aeTimeEvent { long long id; / time event identifier. // 0 long when_sec; / seconds / // 2013-10-18 long when_ms; / milliseconds / // 00:28. 其实是比当前时间多一毫秒 aeTimeProc *timeProc; //serverCron aeEventFinalizerProc *finalizerProc; //NULL void *clientData; //null struct aeTimeEvent *next; } aeTimeEvent; */ ~~~~~~~~~~~~~~~~~~~~ 下面是依次循环执行aeCreateFileEvent函数 这个函数调用了aeApiAddEvent