redis initServer

initServer 主要是对程序进行初始化,包括client list 创建、共享常量字符串、调整文件句柄大小、网络Reactor初始化、监听套接字建立、数据库db初始、时间事件初始化等等

创建共享对象

createSharedObjects() {
//redis都是
shared.crlf = createObject(REDIS_STRING,sdsnew("\r\n"));

}

其中redis里面每个对象都是一个redisObject表示,该结构中和保存数据相关的三个属性分别是type、encoding、ptr,后面会有针对不同对象会讲解

robj *createObject(int type, void *ptr) {
     robj *o = zmalloc(sizeof(*o));
     o->type = type;
     o->encoding = REDIS_ENCODING_RAW;
     o->ptr = ptr;
     o->refcount = 1;

     /* Set the LRU to the current lruclock (minutes resolution). */
     o->lru = LRU_CLOCK();
     return o;
 }

调整文件句柄(adjustOpenFilesLimit)

根据配置的maxfiles 设置系统句柄数目,每次尝试失败 bestlimit -16 重复设置,最低为系统默认句柄数。

while(bestlimit > oldlimit) {
     rlim_t decr_step = 16;

     limit.rlim_cur = bestlimit;
     limit.rlim_max = bestlimit;
     if (setrlimit(RLIMIT_NOFILE,&limit) != -1) break;
     setrlimit_error = errno;

     /* We failed to set file limit to 'bestlimit'. Try with a
      * smaller limit decrementing by a few FDs per iteration. */
     if (bestlimit < decr_step) break;
     bestlimit -= decr_step;
}

Reacor网络创建(aeCreateEventLoop)

aeEventLoop *aeCreateEventLoop(int setsize) {
    aeEventLoop *eventLoop;
    int i;
    //先创建对象
    if ((eventLoop = zmalloc(sizeof(*eventLoop))) == NULL) goto err;
    //注册事件
    eventLoop->events = zmalloc(sizeof(aeFileEvent)*setsize);
    //触发事件
    eventLoop->fired = zmalloc(sizeof(aeFiredEvent)*setsize);
    if (eventLoop->events == NULL || eventLoop->fired == NULL) goto err;
    eventLoop->setsize = setsize;
    eventLoop->lastTime = time(NULL);
    eventLoop->timeEventHead = NULL;
    eventLoop->timeEventNextId = 0;
    eventLoop->stop = 0;
    eventLoop->maxfd = -1;
    eventLoop->beforesleep = NULL;
    if (aeApiCreate(eventLoop) == -1) goto err;
    /* Events with mask == AE_NONE are not set. So let's initialize the
     * vector with it. */
    for (i = 0; i < setsize; i++)
        eventLoop->events[i].mask = AE_NONE;
    return eventLoop;

err:
    if (eventLoop) {
        zfree(eventLoop->events);
        zfree(eventLoop->fired);
        zfree(eventLoop);
    }
    return NULL;
}

网络api redis抽象了epoll、evport、kqueue、select,我们拿epoll举例:

static int aeApiCreate(aeEventLoop *eventLoop) {
    //创建apistate
aeApiState *state = zmalloc(sizeof(aeApiState));

if (!state) return -1;
//事件
    state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize);
    if (!state->events) {
        zfree(state);
        return -1;
}
//epoll fd创建
    state->epfd = epoll_create(1024); /* 1024 is just a hint for the kernel */
    if (state->epfd == -1) {
        zfree(state->events);
        zfree(state);
        return -1;
    }
    eventLoop->apidata = state;
    return 0;
}

aeCreateTimeEvent serverCron定时事件添加

long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
        aeTimeProc *proc, void *clientData,
        aeEventFinalizerProc *finalizerProc)
{
    long long id = eventLoop->timeEventNextId++;
    aeTimeEvent *te;

    te = zmalloc(sizeof(*te));
    if (te == NULL) return AE_ERR;
te->id = id;
//调整时间
    aeAddMillisecondsToNow(milliseconds,&te->when_sec,&te->when_ms);
    te->timeProc = proc;
    te->finalizerProc = finalizerProc;
te->clientData = clientData;
//加入eventLoop->timeEventHead 链表
    te->next = eventLoop->timeEventHead;
    eventLoop->timeEventHead = te;
    return id;
}

监听句柄添加到epoll中

aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL)
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
        aeFileProc *proc, void *clientData)
{
    if (fd >= eventLoop->setsize) {
        errno = ERANGE;
        return AE_ERR;
}

    aeFileEvent *fe = &eventLoop->events[fd];
//添加可读事件
    if (aeApiAddEvent(eventLoop, fd, mask) == -1)
        return AE_ERR;
fe->mask |= mask;
//设置回调
    if (mask & AE_READABLE) fe->rfileProc = proc;
    if (mask & AE_WRITABLE) fe->wfileProc = proc;
    fe->clientData = clientData;
    if (fd > eventLoop->maxfd)
        eventLoop->maxfd = fd;
    return AE_OK;
}

DB 初始化

for (j = 0; j < server.dbnum; j++) {
         server.db[j].dict = dictCreate(&dbDictType,NULL);
         server.db[j].expires = dictCreate(&keyptrDictType,NULL);
         server.db[j].blocking_keys = dictCreate(&keylistDictType,NULL);
         server.db[j].ready_keys = dictCreate(&setDictType,NULL);
         server.db[j].watched_keys = dictCreate(&keylistDictType,NULL);
         server.db[j].eviction_pool = evictionPoolAlloc();
         server.db[j].id = j;
         server.db[j].avg_ttl = 0;
 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值