阿里最近开源了新项目,叫 ApsaraCache,号称对 redis 做了一些优化,但开源分步骤(明显是你们没开发完吧)逐渐放出。这也进一步体现了大公司技术栈的混乱,相信在阿里内部这种类 redis 的玩艺儿绝对也不少。不过不扯这个。在 ApsaraCache 开源一期的优化中,主要有两个功能点:
- 在 redis 4.0 的基础上增加了 memcached 协议的支持
- 对短连接的情况进行了优化
把 ApsaraCache 的代码 down 下来用 Beyond Compare 进行了简单地 diff,发现修改点其实并不多。如图:
除了几个专门处理 memcached 协议的文件之外,其它文件都是小改动,毕竟 memcached 协议支持的命令也不多,所以看起来支持起来也不复杂。
另外就是阿里声称的这个短连接的优化了,刚开始还是想通过 Beyond Compare 来看看他们到底改了哪些文件,不过找起来还是感觉有点麻烦。后来想想自己太蠢,直接去 github 看 commit 就好了:
https://github.com/alibaba/ApsaraCache/commit/8340591bd7fef121d6285efed0007a124ff288d7
改动也不多,其实就是增加了一个函数:
listNode *listAddNodeTailReturnNode(list *list, void *value)
{
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
list->head = list->tail = node;
node->prev = node->next = NULL;
} else {
node->prev = list->tail;
node->next = NULL;
list->tail->next = node;
list->tail = node;
}
list->len++;
return node; //===== 区别就这一行
}
来取代原本的
list *listAddNodeTail(list *list, void *value)
{
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
list->head = list->tail = node;
node->prev = node->next = NULL;
} else {
node->prev = list->tail;
node->next = NULL;
list->tail->next = node;
list->tail = node;
}
list->len++;
return list; //===== 区别就这里一行
}
两个函数顾名思义,实际上新函数就是在往 server.clients 这个链表里塞当前的 client 的时候,把位置指针也返回回来,并在当前的 client struct 里增加了新字段,用于存储这个返回的,在 server.clients 中的位置。
代码如下:
struct client {
....
listNode *client_list_node; /* list node in client list */
....
}
其实逻辑很简单,因为我删除 client 的时候是用 server.clients 链表删除该 client,那我 client struct 里只要存储了他在 clients 链表中的位置那就不用去做这个链表遍历啦。这样在 unlinkClient 的时候,少了一步 listSearchKey(server.clients,c) 的操作。redis 原来的 listSearchKey 也没什么神奇的,就是链表的线性查找。
listNode *listSearchKey(list *list, void *key)
{
listIter iter;
listNode *node;
listRewind(list, &iter);
while((node = listNext(&iter)) != NULL) {
if (list->match) {
if (list->match(node->value, key)) {
return node;
}
} else {
if (key == node->value) {
return node;
}
}
}
return NULL;
}
短连接的时候 server.clients 应该会是比较长的链表(猜测)。
再回想一下当初在渣雷的短暂时光。。这种互相存储指针引用的做法在 c 里还蛮常见的。
之后有时间的话看到官方更新了 ApsaraCache 也会再跟进一下修改内容吧,大概。