Open imjustfly opened 7 years ago
@imjustfly 如果你 patch 成功了。能给我一个 PR 嘛?
这不怪我。Redis 每个版本都是重构,代码数据结构改懂很大 = 重写。这个坑我已经踩过好几次了,从 2.x 到 3.x 再到给 redis 打 patch,每次都不兼容。没有办法,需要你手动 fix,不过好在这部分难度其实不大。几个小时就能搞定。
BTW,到 4.2 的时候,Redis 又改代码了,几乎重构。
@imjustfly 另外,我觉得是你理解错了。
slots.c 中的 dict 的声明类型是 hashSlotType
,而 slots_async.c 里面的 dict 声明类型基本上都是 setDictType
。这两种在 redis3.x 分别是用 sds
和 obj
作为 key。但是在 redis4.x 里面,作者修改了 setDictType
的定义,也改成了 sds
作为 key,就是说,其实是 redis 自己前后不兼容了。
https://github.com/antirez/redis/blob/3.2/src/server.c#L540
/* Sets type hash table */
dictType setDictType = {
dictEncObjHash, /* hash function */
NULL, /* key dup */
NULL, /* val dup */
dictEncObjKeyCompare, /* key compare */
dictObjectDestructor, /* key destructor */
NULL /* val destructor */
};
https://github.com/antirez/redis/blob/4.0/src/server.c#L555
/* Set dictionary type. Keys are SDS strings, values are ot used. */
dictType setDictType = {
dictSdsHash, /* hash function */
NULL, /* key dup */
NULL, /* val dup */
dictSdsKeyCompare, /* key compare */
dictSdsDestructor, /* key destructor */
NULL /* val destructor */
};
不是我的原因。
@spinlock 收到!我对 redis 代码的历史确实没仔细看。
我这边的patch,redis自带的测试用例都过了,codis slot 相关的命令正在测试,稍等我给你提一下。
我应该会在extern 目录下建一个4.0.1的 redis 目录,里面有一个patch文件提供codis的功能。
slots.c 和 slots_async.c 中都涉及到对一些dict数据结构的操作,一些操作比如
dictAdd
dictFind
所使用的 key 在 slot.c 中都为sds
,而在 slots_async.c 中都为robj *
我自己尝试手动合并 codis 的 patch到 redis 4.0.1 版本中,slots_async.c中对dict 的 find 和 add 操作会导致崩溃:
原因是 调用真正的 hash 函数
siphash
时,如果 key 为robj *
类型,传递给 siphash 函数的第一个参数const uint8_t *in
后,内存地址就越界了.将所有 key 为
robj *
的地方改成使用sds
(sdsdup(robj->ptr)
for add,robj->ptr
for find & delete) 可以解决这问题。redis 源码对dict使用的key也为sds,是否考虑slots_async.c
中对key的类型做一下修改,和其他代码统一起来?