参考http://pauladamsmith.com/articles/redis-under-the-hood.html#event-loop-setup
http://www.yiihsia.com/tag/redis/
Redis Server端
initServerConfig()首先初始化配置信息
这个函数里面会设置server的相关信息如:port、dbnum、Command table等
先创建Command命令的字典server.commands = dictCreate(&commandTableDictType,NULL)
populateCommandTable()就是将常用的命令加入Command字典
loadServerConfig根据命令行参数设置server的配置文件;并且导入配置文件;根据配置文件设置server的port等信息
redis.c 的main函数里面的initServer会执行如下操作
如果需要配置文件里面配置了后台运行程序,那么就fork一个子进程;然后父进程exit;让子进程运行程序
initServer
忽略SIGPIPE写端关闭信号 和SIGHUP终端退出信号
生成client 、slaves 以及monitors等的list
创建 sharedObjectsStruct 其中包括robj *crlf, *ok, *err,
aeCreateEventLoop创建aeEventLoop *eventLoop,主要是做一些初始化工作并create一个epollfd
这个函数里面会调用aeApiCreate来真正的create一个epoll的描述符state->epfd=epoll_create(1024)
当port为合法的时候就会去调用anetTcpServer;这个函数会anetCreateSocket用于监听客户端请求的socketfd;然后anetListen会bind 还会listen开始监听客户端请求
anetCreateSocket(err,AF_INET)这个函数里会创建一个socket然后会设置socket的相关属性:如设置setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));这样如果一个服务断掉之后不用等待很久就可以立即使用这个端口
接下来会dictCreate创建dict(此处略去一万字)
aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL)如果有超时时间发生会去调用serverCron这个回调函数
aeCreateTimeEvent里面会设置超时时间;将其添加到timeEventHead里面并作为list的head;并设置这个event的回调函数是serverCron
接下来应该看的就是serverCron干了些什么
打印非空db的一些信息,log功能
如果当前没有后台运行dump数据保存到文件的进程,则可以根据内存使用情况重新调整hashTables大小
日志输出一些client的连接信息
检测idle的client 连接,关闭idle连接
判断是否有正在进行dump数据到文件的后台进程;如果有判断是否已经结束,进行结束后的一些工作(这个跟replication有关,后续详细说明);没有则判断是否需要启动新的进程dump数据到文件
处理expired的key
vmSwapOut功能,如果启动了vm选项,则判断是否超过vmMaxMemory,如果超过进行value的swap
判断如果server是slave,则连接master,发送sync命令,和master同步数据
aeCreateFileEvent他的回调函数是acceptTcpHandler;aeCreateFileEvent这里面主要是将要监听的sockfd添加到epoll的事件队列里面epoll_ctl(state->epfd,op,fd,&ee)
acceptTcpHandler至于他的回调函数要干的事情就是anetTcpAccept接受连接;将与客户端已经建立连接的cfd加入到epoll事件队列并调用它的回调函数
acceptCommonHandler这个函数就是将与客户端已经建立连接的cfd加入到epoll事件队列 他会调用createClient:他会设置cfd为非阻塞并且为TcpNoDela然后aeCreateFileEvent将cfd加入到epoll事件队列里面;aeCreateFileEvent的回调函数是readQueryFromClient;处理客户端的Query
createClient(fd)设置fd的属性并且调用aeCreateFileEvent(server.el,fd,AE_READABLE, readQueryFromClient, c) 将fd加入到epoll队列里面;设置Client的若干属性;将该Client加入.server.client的尾部;他的回调函数是readQueryFromClient
readQueryFromClient的作用是读入客户端输入的数据,并调用processInputBuffer解析并处理用户的请求
如果vm是可用的那么执行 vmInit()(此处略去一万字)
aeSetBeforeSleepProc(server.el,beforeSleep):当 Redis进入事件驱动的main循环之前即获取准备就绪事件之前需要完成的工作:这个他会去试着为没有被阻塞的客户处理他们等待在buffer中的命令;并且会调用flushAppendOnlyFile 写AOF缓冲区在硬盘上
如果vm是可用的那将已经IO准备就绪的进行swap
执行非阻塞Client命令
写AOF到disk上
aeMain(server.el)在每次进行aeProcessEvent之前都需要调用beforeSleep:
aeProcessEvent获得准备就绪的事件;并且调用它的回调函数.检查超时事件(线性扫描超市队列)并执行超时事件的回调函数
aeDeleteEventLoop(server.el)
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com