之前看了些Redis,这是一个优秀的源代码库, 不过4万多行的源代码,这里做一个简要分析
Redis采用Key-value 的内存数据库
服务器端部分源码
1.adlist.c 双链表代码
ae.c/ae_epoll.c/ae_kqueue.c/ae_select.c 服务器端接收event模式
anet.c socket部分
aof.c aof 文件
config.c 配置文件解析
db.c 数据库文件, 主要是hash查找
dict.c hash 处理
network.c //处理客户端命令
redis.c // 程序入口, 初始化
t_hash.c/t_list.c/t_set.c/t_string.c/t_zset.c redis的数据类型和操作
ziplist.c/zipmap.c 压缩表数据
zmalloc.c 内存管理部分
multi.c 事务处理
rdb.c 本地数据库操作
replication.c 主从数据库复制操作
object.c object.c 处理
Redis.c main 函数分析
1. main
主要完成Redisserver的初始化和主要的处理函数
->初始化hash种子 -> initServerConfig();
-> initServerConfig // 初始化RedisServer
-> populateCommandTable() 注册命令table
->initServer
->createSharedObjects(); //创建redisobject
->server.el = aeCreateEventLoop(server.maxclients+REDIS_EVENTLOOP_FDSET_INCR); //创建eventLoop
->server.db = zmalloc(sizeof(redisDb)*server.dbnum); //创建db
->aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) //设time event 为serverCron (1)serverCron
->(aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE,acceptTcpHandler,NULL, NULL ) //处理客户端 2)acceptTcpHandler
->bioInit();
->aeSetBeforeSleepProc(server.el,beforeSleep); //set beforesleep 函数 3) beforeSleep
->aeMain(server.el); //while循环下
->beforesleep
-> aeProcessEvents //处理process events
最后跳转到aeMain,处理客户端的请求
2)serverCron 分析
serverCron基本上是Redis的时钟中断,主要完成以下工作
1)激活过期的key(key lru 处理)
2)更新统计信息 (trackOperationsPersecond)
3) 实现软件watchdog
4) db hash表的rehash
5)clients timeout处理
6)重链接处理
clientsCrons (clients的异步处理)
databasesCron Redis 的后台操作
flushAppendOnlyFile (写AOF文件到磁盘)
replicationCron 检测传送错误
3)acceptTcpHandler (networking.c)
在aeMain中通过c->readproc调用此函数
1. anetTcpAccept 服务器端通过accept接收请求
2.acceptCommonHandler 获得链接后,建立RedisClient对象,
调用createClient -> listAddNodeTail(server.clients, c);
4) beforesleep
activeRetireCycle (去掉一些timeout键值)
if ((c->querybuf && sdslen(c->querybuf))
processInputBuffer(c) (处理输入buffer,networking.c) (4)processInputBuffer
5)processInputBuffer (network.c) (处理命令的流程
processCommand(c)
->1) c->cmd = lookupCommand 解析buffer并获得命令
-> 2)各种错误处理并调用addReply
- >3) call(c, REDIS_CALL_FULL)
->c->cmd->proc(c) 执行命令
-> 特殊命令处理和收尾工作
2. aeProcessEvents 函数
服务器端通过epoll获得请求
1)aeApiPoll(eventLoop, tvp) ; 主要调用eventpoll获得event处理 (ae.c)
2) fe->rfileProc 或者fe->wfileProc . 实际为 acceptTcpHandler
3) processtimeEvent
te->timeProc(eventLoop, id, te->clientData); serverCron