首先源码位于redis/src/server.c里面 1.main函数里面首先检查redis-server启动时的启动选项,加载配置项等等.我们最关心的,命令回调函数与CMD的绑定在这里初始化。贴出所有代码 struct redisCommand redisCommandTable[] = { {“module”,moduleCommand,-2,“as”,0,NULL,0,0,0,0,0}, {“get”,getCommand,2,“rF”,0,NULL,1,1,1,0,0}, {“set”,setCommand,-3,“wm”,0,NULL,1,1,1,0,0}, {“setnx”,setnxCommand,3,“wmF”,0,NULL,1,1,1,0,0}, {“setex”,setexCommand,4,“wm”,0,NULL,1,1,1,0,0}, {“psetex”,psetexCommand,4,“wm”,0,NULL,1,1,1,0,0}, {“append”,appendCommand,3,“wm”,0,NULL,1,1,1,0,0}, {“strlen”,strlenCommand,2,“rF”,0,NULL,1,1,1,0,0}, {“del”,delCommand,-2,“w”,0,NULL,1,-1,1,0,0}, {“unlink”,unlinkCommand,-2,“wF”,0,NULL,1,-1,1,0,0}, {“exists”,existsCommand,-2,“rF”,0,NULL,1,-1,1,0,0}, {“setbit”,setbitCommand,4,“wm”,0,NULL,1,1,1,0,0}, {“getbit”,getbitCommand,3,“rF”,0,NULL,1,1,1,0,0}, {“bitfield”,bitfieldCommand,-2,“wm”,0,NULL,1,1,1,0,0}, {“setrange”,setrangeCommand,4,“wm”,0,NULL,1,1,1,0,0}, {“getrange”,getrangeCommand,4,“r”,0,NULL,1,1,1,0,0}, {“substr”,getrangeCommand,4,“r”,0,NULL,1,1,1,0,0}, {“incr”,incrCommand,2,“wmF”,0,NULL,1,1,1,0,0}, {“decr”,decrCommand,2,“wmF”,0,NULL,1,1,1,0,0}, {“mget”,mgetCommand,-2,“rF”,0,NULL,1,-1,1,0,0}, {“rpush”,rpushCommand,-3,“wmF”,0,NULL,1,1,1,0,0}, {“lpush”,lpushCommand,-3,“wmF”,0,NULL,1,1,1,0,0}, {“rpushx”,rpushxCommand,-3,“wmF”,0,NULL,1,1,1,0,0}, {“lpushx”,lpushxCommand,-3,“wmF”,0,NULL,1,1,1,0,0}, {“linsert”,linsertCommand,5,“wm”,0,NULL,1,1,1,0,0}, {“rpop”,rpopCommand,2,“wF”,0,NULL,1,1,1,0,0}, {“lpop”,lpopCommand,2,“wF”,0,NULL,1,1,1,0,0}, {“brpop”,brpopCommand,-3,“ws”,0,NULL,1,-2,1,0,0}, {“brpoplpush”,brpoplpushCommand,4,“wms”,0,NULL,1,2,1,0,0}, {“blpop”,blpopCommand,-3,“ws”,0,NULL,1,-2,1,0,0}, {“llen”,llenCommand,2,“rF”,0,NULL,1,1,1,0,0}, {“lindex”,lindexCommand,3,“r”,0,NULL,1,1,1,0,0}, {“lset”,lsetCommand,4,“wm”,0,NULL,1,1,1,0,0}, {“lrange”,lrangeCommand,4,“r”,0,NULL,1,1,1,0,0}, {“ltrim”,ltrimCommand,4,“w”,0,NULL,1,1,1,0,0}, {“lrem”,lremCommand,4,“w”,0,NULL,1,1,1,0,0}, {“rpoplpush”,rpoplpushCommand,3,“wm”,0,NULL,1,2,1,0,0}, {“sadd”,saddCommand,-3,“wmF”,0,NULL,1,1,1,0,0}, {“srem”,sremCommand,-3,“wF”,0,NULL,1,1,1,0,0}, {“smove”,smoveCommand,4,“wF”,0,NULL,1,2,1,0,0}, {“sismember”,sismemberCommand,3,“rF”,0,NULL,1,1,1,0,0}, {“scard”,scardCommand,2,“rF”,0,NULL,1,1,1,0,0}, {“spop”,spopCommand,-2,“wRF”,0,NULL,1,1,1,0,0}, {“srandmember”,srandmemberCommand,-2,“rR”,0,NULL,1,1,1,0,0}, {“sinter”,sinterCommand,-2,“rS”,0,NULL,1,-1,1,0,0}, {“sinterstore”,sinterstoreCommand,-3,“wm”,0,NULL,1,-1,1,0,0}, {“sunion”,sunionCommand,-2,“rS”,0,NULL,1,-1,1,0,0}, {“sunionstore”,sunionstoreCommand,-3,“wm”,0,NULL,1,-1,1,0,0}, {“sdiff”,sdiffCommand,-2,“rS”,0,NULL,1,-1,1,0,0}, {“sdiffstore”,sdiffstoreCommand,-3,“wm”,0,NULL,1,-1,1,0,0}, {“smembers”,sinterCommand,2,“rS”,0,NULL,1,1,1,0,0}, {“sscan”,sscanCommand,-3,“rR”,0,NULL,1,1,1,0,0}, {“zadd”,zaddCommand,-4,“wmF”,0,NULL,1,1,1,0,0}, {“zincrby”,zincrbyCommand,4,“wmF”,0,NULL,1,1,1,0,0}, {“zrem”,zremCommand,-3,“wF”,0,NULL,1,1,1,0,0}, {“zremrangebyscore”,zremrangebyscoreCommand,4,“w”,0,NULL,1,1,1,0,0}, {“zremrangebyrank”,zremrangebyrankCommand,4,“w”,0,NULL,1,1,1,0,0}, {“zremrangebylex”,zremrangebylexCommand,4,“w”,0,NULL,1,1,1,0,0}, {“zunionstore”,zunionstoreCommand,-4,“wm”,0,zunionInterGetKeys,0,0,0,0,0}, {“zinterstore”,zinterstoreCommand,-4,“wm”,0,zunionInterGetKeys,0,0,0,0,0}, {“zrange”,zrangeCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“zrangebyscore”,zrangebyscoreCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“zrevrangebyscore”,zrevrangebyscoreCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“zrangebylex”,zrangebylexCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“zrevrangebylex”,zrevrangebylexCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“zcount”,zcountCommand,4,“rF”,0,NULL,1,1,1,0,0}, {“zlexcount”,zlexcountCommand,4,“rF”,0,NULL,1,1,1,0,0}, {“zrevrange”,zrevrangeCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“zcard”,zcardCommand,2,“rF”,0,NULL,1,1,1,0,0}, {“zscore”,zscoreCommand,3,“rF”,0,NULL,1,1,1,0,0}, {“zrank”,zrankCommand,3,“rF”,0,NULL,1,1,1,0,0}, {“zrevrank”,zrevrankCommand,3,“rF”,0,NULL,1,1,1,0,0}, {“zscan”,zscanCommand,-3,“rR”,0,NULL,1,1,1,0,0}, {“zpopmin”,zpopminCommand,-2,“wF”,0,NULL,1,1,1,0,0}, {“zpopmax”,zpopmaxCommand,-2,“wF”,0,NULL,1,1,1,0,0}, {“bzpopmin”,bzpopminCommand,-3,“wsF”,0,NULL,1,-2,1,0,0}, {“bzpopmax”,bzpopmaxCommand,-3,“wsF”,0,NULL,1,-2,1,0,0}, {“hset”,hsetCommand,-4,“wmF”,0,NULL,1,1,1,0,0}, {“hsetnx”,hsetnxCommand,4,“wmF”,0,NULL,1,1,1,0,0}, {“hget”,hgetCommand,3,“rF”,0,NULL,1,1,1,0,0}, {“hmset”,hsetCommand,-4,“wmF”,0,NULL,1,1,1,0,0}, {“hmget”,hmgetCommand,-3,“rF”,0,NULL,1,1,1,0,0}, {“hincrby”,hincrbyCommand,4,“wmF”,0,NULL,1,1,1,0,0}, {“hincrbyfloat”,hincrbyfloatCommand,4,“wmF”,0,NULL,1,1,1,0,0}, {“hdel”,hdelCommand,-3,“wF”,0,NULL,1,1,1,0,0}, {“hlen”,hlenCommand,2,“rF”,0,NULL,1,1,1,0,0}, {“hstrlen”,hstrlenCommand,3,“rF”,0,NULL,1,1,1,0,0}, {“hkeys”,hkeysCommand,2,“rS”,0,NULL,1,1,1,0,0}, {“hvals”,hvalsCommand,2,“rS”,0,NULL,1,1,1,0,0}, {“hgetall”,hgetallCommand,2,“rR”,0,NULL,1,1,1,0,0}, {“hexists”,hexistsCommand,3,“rF”,0,NULL,1,1,1,0,0}, {“hscan”,hscanCommand,-3,“rR”,0,NULL,1,1,1,0,0}, {“incrby”,incrbyCommand,3,“wmF”,0,NULL,1,1,1,0,0}, {“decrby”,decrbyCommand,3,“wmF”,0,NULL,1,1,1,0,0}, {“incrbyfloat”,incrbyfloatCommand,3,“wmF”,0,NULL,1,1,1,0,0}, {“getset”,getsetCommand,3,“wm”,0,NULL,1,1,1,0,0}, {“mset”,msetCommand,-3,“wm”,0,NULL,1,-1,2,0,0}, {“msetnx”,msetnxCommand,-3,“wm”,0,NULL,1,-1,2,0,0}, {“randomkey”,randomkeyCommand,1,“rR”,0,NULL,0,0,0,0,0}, {“select”,selectCommand,2,“lF”,0,NULL,0,0,0,0,0}, {“swapdb”,swapdbCommand,3,“wF”,0,NULL,0,0,0,0,0}, {“move”,moveCommand,3,“wF”,0,NULL,1,1,1,0,0}, {“rename”,renameCommand,3,“w”,0,NULL,1,2,1,0,0}, {“renamenx”,renamenxCommand,3,“wF”,0,NULL,1,2,1,0,0}, {“expire”,expireCommand,3,“wF”,0,NULL,1,1,1,0,0}, {“expireat”,expireatCommand,3,“wF”,0,NULL,1,1,1,0,0}, {“pexpire”,pexpireCommand,3,“wF”,0,NULL,1,1,1,0,0}, {“pexpireat”,pexpireatCommand,3,“wF”,0,NULL,1,1,1,0,0}, {“keys”,keysCommand,2,“rS”,0,NULL,0,0,0,0,0}, {“scan”,scanCommand,-2,“rR”,0,NULL,0,0,0,0,0}, {“dbsize”,dbsizeCommand,1,“rF”,0,NULL,0,0,0,0,0}, {“auth”,authCommand,2,“sltF”,0,NULL,0,0,0,0,0}, {“ping”,pingCommand,-1,“tF”,0,NULL,0,0,0,0,0}, {“echo”,echoCommand,2,“F”,0,NULL,0,0,0,0,0}, {“save”,saveCommand,1,“as”,0,NULL,0,0,0,0,0}, {“bgsave”,bgsaveCommand,-1,“as”,0,NULL,0,0,0,0,0}, {“bgrewriteaof”,bgrewriteaofCommand,1,“as”,0,NULL,0,0,0,0,0}, {“shutdown”,shutdownCommand,-1,“aslt”,0,NULL,0,0,0,0,0}, {“lastsave”,lastsaveCommand,1,“RF”,0,NULL,0,0,0,0,0}, {“type”,typeCommand,2,“rF”,0,NULL,1,1,1,0,0}, {“multi”,multiCommand,1,“sF”,0,NULL,0,0,0,0,0}, {“exec”,execCommand,1,“sM”,0,NULL,0,0,0,0,0}, {“discard”,discardCommand,1,“sF”,0,NULL,0,0,0,0,0}, {“sync”,syncCommand,1,“ars”,0,NULL,0,0,0,0,0}, {“psync”,syncCommand,3,“ars”,0,NULL,0,0,0,0,0}, {“replconf”,replconfCommand,-1,“aslt”,0,NULL,0,0,0,0,0}, {“flushdb”,flushdbCommand,-1,“w”,0,NULL,0,0,0,0,0}, {“flushall”,flushallCommand,-1,“w”,0,NULL,0,0,0,0,0}, {“sort”,sortCommand,-2,“wm”,0,sortGetKeys,1,1,1,0,0}, {“info”,infoCommand,-1,“ltR”,0,NULL,0,0,0,0,0}, {“monitor”,monitorCommand,1,“as”,0,NULL,0,0,0,0,0}, {“ttl”,ttlCommand,2,“rFR”,0,NULL,1,1,1,0,0}, {“touch”,touchCommand,-2,“rF”,0,NULL,1,1,1,0,0}, {“pttl”,pttlCommand,2,“rFR”,0,NULL,1,1,1,0,0}, {“persist”,persistCommand,2,“wF”,0,NULL,1,1,1,0,0}, {“slaveof”,replicaofCommand,3,“ast”,0,NULL,0,0,0,0,0}, {“replicaof”,replicaofCommand,3,“ast”,0,NULL,0,0,0,0,0}, {“role”,roleCommand,1,“lst”,0,NULL,0,0,0,0,0}, {“debug”,debugCommand,-2,“as”,0,NULL,0,0,0,0,0}, {“config”,configCommand,-2,“last”,0,NULL,0,0,0,0,0}, {“subscribe”,subscribeCommand,-2,“pslt”,0,NULL,0,0,0,0,0}, {“unsubscribe”,unsubscribeCommand,-1,“pslt”,0,NULL,0,0,0,0,0}, {“psubscribe”,psubscribeCommand,-2,“pslt”,0,NULL,0,0,0,0,0}, {“punsubscribe”,punsubscribeCommand,-1,“pslt”,0,NULL,0,0,0,0,0}, {“publish”,publishCommand,3,“pltF”,0,NULL,0,0,0,0,0}, {“pubsub”,pubsubCommand,-2,“pltR”,0,NULL,0,0,0,0,0}, {“watch”,watchCommand,-2,“sF”,0,NULL,1,-1,1,0,0}, {“unwatch”,unwatchCommand,1,“sF”,0,NULL,0,0,0,0,0}, {“cluster”,clusterCommand,-2,“a”,0,NULL,0,0,0,0,0}, {“restore”,restoreCommand,-4,“wm”,0,NULL,1,1,1,0,0}, {“restore-asking”,restoreCommand,-4,“wmk”,0,NULL,1,1,1,0,0}, {“migrate”,migrateCommand,-6,“wR”,0,migrateGetKeys,0,0,0,0,0}, {“asking”,askingCommand,1,“F”,0,NULL,0,0,0,0,0}, {“readonly”,readonlyCommand,1,“F”,0,NULL,0,0,0,0,0}, {“readwrite”,readwriteCommand,1,“F”,0,NULL,0,0,0,0,0}, {“dump”,dumpCommand,2,“rR”,0,NULL,1,1,1,0,0}, {“object”,objectCommand,-2,“rR”,0,NULL,2,2,1,0,0}, {“memory”,memoryCommand,-2,“rR”,0,NULL,0,0,0,0,0}, {“client”,clientCommand,-2,“as”,0,NULL,0,0,0,0,0}, {“eval”,evalCommand,-3,“s”,0,evalGetKeys,0,0,0,0,0}, {“evalsha”,evalShaCommand,-3,“s”,0,evalGetKeys,0,0,0,0,0}, {“slowlog”,slowlogCommand,-2,“aR”,0,NULL,0,0,0,0,0}, {“script”,scriptCommand,-2,“s”,0,NULL,0,0,0,0,0}, {“time”,timeCommand,1,“RF”,0,NULL,0,0,0,0,0}, {“bitop”,bitopCommand,-4,“wm”,0,NULL,2,-1,1,0,0}, {“bitcount”,bitcountCommand,-2,“r”,0,NULL,1,1,1,0,0}, {“bitpos”,bitposCommand,-3,“r”,0,NULL,1,1,1,0,0}, {“wait”,waitCommand,3,“s”,0,NULL,0,0,0,0,0}, {“command”,commandCommand,0,“ltR”,0,NULL,0,0,0,0,0}, {“geoadd”,geoaddCommand,-5,“wm”,0,NULL,1,1,1,0,0}, {“georadius”,georadiusCommand,-6,“w”,0,georadiusGetKeys,1,1,1,0,0}, {“georadius_ro”,georadiusroCommand,-6,“r”,0,georadiusGetKeys,1,1,1,0,0}, {“georadiusbymember”,georadiusbymemberCommand,-5,“w”,0,georadiusGetKeys,1,1,1,0,0}, {“georadiusbymember_ro”,georadiusbymemberroCommand,-5,“r”,0,georadiusGetKeys,1,1,1,0,0}, {“geohash”,geohashCommand,-2,“r”,0,NULL,1,1,1,0,0}, {“geopos”,geoposCommand,-2,“r”,0,NULL,1,1,1,0,0}, {“geodist”,geodistCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“pfselftest”,pfselftestCommand,1,“a”,0,NULL,0,0,0,0,0}, {“pfadd”,pfaddCommand,-2,“wmF”,0,NULL,1,1,1,0,0}, {“pfcount”,pfcountCommand,-2,“r”,0,NULL,1,-1,1,0,0}, {“pfmerge”,pfmergeCommand,-2,“wm”,0,NULL,1,-1,1,0,0}, {“pfdebug”,pfdebugCommand,-3,“w”,0,NULL,0,0,0,0,0}, {“xadd”,xaddCommand,-5,“wmFR”,0,NULL,1,1,1,0,0}, {“xrange”,xrangeCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“xrevrange”,xrevrangeCommand,-4,“r”,0,NULL,1,1,1,0,0}, {“xlen”,xlenCommand,2,“rF”,0,NULL,1,1,1,0,0}, {“xread”,xreadCommand,-4,“rs”,0,xreadGetKeys,1,1,1,0,0}, {“xreadgroup”,xreadCommand,-7,“ws”,0,xreadGetKeys,1,1,1,0,0}, {“xgroup”,xgroupCommand,-2,“wm”,0,NULL,2,2,1,0,0}, {“xsetid”,xsetidCommand,3,“wmF”,0,NULL,1,1,1,0,0}, {“xack”,xackCommand,-4,“wF”,0,NULL,1,1,1,0,0}, {“xpending”,xpendingCommand,-3,“rR”,0,NULL,1,1,1,0,0}, {“xclaim”,xclaimCommand,-6,“wRF”,0,NULL,1,1,1,0,0}, {“xinfo”,xinfoCommand,-2,“rR”,0,NULL,2,2,1,0,0}, {“xdel”,xdelCommand,-3,“wF”,0,NULL,1,1,1,0,0}, {“xtrim”,xtrimCommand,-2,“wFR”,0,NULL,1,1,1,0,0}, {“post”,securityWarningCommand,-1,“lt”,0,NULL,0,0,0,0,0}, {“host:”,securityWarningCommand,-1,“lt”,0,NULL,0,0,0,0,0}, {“latency”,latencyCommand,-2,“aslt”,0,NULL,0,0,0,0,0}, {“lolwut”,lolwutCommand,-1,“r”,0,NULL,0,0,0,0,0} } 这里就是服务器能提供的所有功能的,第一个是命令,第二个是命令的执行回调函数
2.初始化服务器initServer(),这个函数是关键函数.因为大体所有的成员变量.这里罗列下重要的几个成员变量和成员函数
server.el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR); server.el 所有的的事件都会挂载在server.el上.包括服务端的socket accept的监听 ,建立连接后socket读写的监听,pipe的监听
server.db = zmalloc(sizeof(redisDb)*server.dbnum); 数据库db的创建,默认会创建16个DB
listenToPort(server.port,server.ipfd,&server.ipfd_count) == C_ERR) 创建服务器socket并将其添加到server.el event对象里面
if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL) == AE_ERR) 这里是将服务器accept的响应回调函数 acceptTcpHandler 挂到el上去, 而当acceptTcpHandler与客户端建立连接后,会将新产生的socket与其对应的读写回调函数挂到el上去,实现代码
3。彩蛋的打印了,这个比较有意思。贴下代码 最后就一定是开户一个while死循环了,等待客户端的连接和操作。它的实现在 aeMain(server.el);这个调用里面,由出实现 就是一个while循环,主体函数就是aeProcessEvents,然后就等客户端CMD了 poll(阻塞等待) -> fd read | fd write aeApiPoll(eventLoop, tvp); 这个函数执行poll,对所有加入的fd 进行阻塞监控。有事件参生后中断阻塞响应客户端命令,贴图如下到此结束。大体过程如下,剩下的就是仔细研究每个命令对应的回调函数。看函数的实现方式,主要是了解数据库DB的存储和读取的方式和策略。这部分本人也没仔细阅读,只是研究了下服务器与客户端的大体框架流程