You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

50 lines
3.3 KiB
Markdown

2 years ago
# 期中测试题答案 | 这些问题你都答对了吗?
你好,我是蒋德钧。这节课,我来给你公布一下期中考试中问答题的答案。
## 第一题
Redis源码中实现的哈希表在rehash时会调用dictRehash函数。dictRehash函数的原型如下它的参数n表示本次rehash要搬移n个哈希桶bucket中的数据。假设dictRehash被调用并且n的传入值为10。但是在dictRehash查找的10个bucket中前5个bucket有数据而后5个bucket没有数据那么本次调用dictRehash是否就只搬移了前5个bucket中的数据
```plain
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实例。这个调用关系如下
```plain
aeCreateEventLoop --> aeApiCreate --> epoll_create
```
然后当事件驱动框架初始化完成后initServer函数就会调用aeCreateFileEvent函数而aeCreateFileEvent函数会调用aeApiAddEvent函数进而调用epoll\_ctl将监听套接字加入监听列表。这个调用关系为
```plain
aeCreateFileEvent --> aeApiAddEvent --> epoll_ctl
```
这样一来Redis server在完成初始化后就会调用aeMain函数进入事件框架的循环流程。在这个流程中**aeProcessEvents函数**会被循环调用用于不断处理事件。aeProcessEvents函数会调用aeApiPoll函数而aeApiPoll函数就会调用epoll\_wait进而获取就绪的套接字从而可以处理套接字上的事件了。这个调用关系你可以参考以下代码
```plain
aeMain --> aeProcessEvents --> aeApiPoll --> epoll_wait
```
好了,这节课就到这里。期中周转眼就过去了一大半,希望你抓住最后的几天时间,好好地巩固一下所学的内容。我们下节课再见。