gitbook/Redis源码剖析与实战/docs/418672.md
2022-09-03 22:05:03 +08:00

3.3 KiB
Raw Blame History

期中测试题答案 | 这些问题你都答对了吗?

你好,我是蒋德钧。这节课,我来给你公布一下期中考试中问答题的答案。

第一题

Redis源码中实现的哈希表在rehash时会调用dictRehash函数。dictRehash函数的原型如下它的参数n表示本次rehash要搬移n个哈希桶bucket中的数据。假设dictRehash被调用并且n的传入值为10。但是在dictRehash查找的10个bucket中前5个bucket有数据而后5个bucket没有数据那么本次调用dictRehash是否就只搬移了前5个bucket中的数据

int dictRehash(dict *d, int n) 

答案分析

当Redis哈希表在做rehash搬移数据时如果遇到空的bucket那么Redis会跳过空的bucket再查找下一个bucket。但是在dictRehash函数中是使用了empty_visits变量来记录跳过的空bucket数量而empty_visits的值是被初始化成n*10也就是要搬移的bucket数量的10倍。

因此如果rehash过程中已经跳过了empty_visits数量的空bucket那么本次dictRehash的执行就会直接返回了而不会再查找bucket。这样设计的目的也是为了避免本次rehash的执行一直无法结束影响正常的请求处理

所以在题述场景中dictRehash函数会在找到50个空bucket时直接结束执行即使此时还没有完成10个bucket数据的搬移。而如果在查找的10个bucket后面紧接着就有5个bucket有数据那么本次调用dictRehash仍然搬移了10个bucket的数据。

第二题

Redis的事件驱动框架是基于操作系统IO多路复用机制进行了封装以Linux的epoll机制为例该机制调用epoll_create函数创建epoll实例再调用epoll_ctl将监听的套接字加入监听列表最后调用epoll_wait获取就绪的套接字再进行处理。请简述Redis事件驱动框架中哪些函数和epoll机制各主要函数有对应的调用关系。

答案分析

Redis在initServer函数中调用了aeCreateEventLoop函数初始化事件框架其中aeCreateEventLoop函数会调用aeApiCreate函数而如果IO多路复用机制使用的是epoll机制那么aeApiCreate函数就会调用epoll_create函数创建epoll实例。这个调用关系如下

aeCreateEventLoop --> aeApiCreate --> epoll_create

然后当事件驱动框架初始化完成后initServer函数就会调用aeCreateFileEvent函数而aeCreateFileEvent函数会调用aeApiAddEvent函数进而调用epoll_ctl将监听套接字加入监听列表。这个调用关系为

aeCreateFileEvent --> aeApiAddEvent --> epoll_ctl

这样一来Redis server在完成初始化后就会调用aeMain函数进入事件框架的循环流程。在这个流程中aeProcessEvents函数会被循环调用用于不断处理事件。aeProcessEvents函数会调用aeApiPoll函数而aeApiPoll函数就会调用epoll_wait进而获取就绪的套接字从而可以处理套接字上的事件了。这个调用关系你可以参考以下代码

aeMain --> aeProcessEvents --> aeApiPoll --> epoll_wait

好了,这节课就到这里。期中周转眼就过去了一大半,希望你抓住最后的几天时间,好好地巩固一下所学的内容。我们下节课再见。