Redis 中 Key 为什么也使用 SDS 而不是 C 字符串呢?

2021-05-21 00:18:46 +08:00
 jay1002008

SDS 类型具有几大优势:

  1. 常数复杂度获取字符串长度
  2. 杜绝缓冲区溢出
  3. 减少修改字符串长度时所需的内存重分配次数
  4. 二进制安全
  5. 兼容部分 C 字符串函数

但是,Redis Key 不需要修改,所以大部分优势都不存在了,为什么还需要 SDS 类型呢,使用 C 字符串不香吗?

2846 次点击
所在节点    Redis
16 条回复
CEBBCAT
2021-05-21 00:33:02 +08:00
我个人觉得,二进制安全就已经很诱人了。另外搜到一篇博客,一起贴上来:

https://redisbook.readthedocs.io/en/latest/internal-datastruct/sds.html
ebingtel
2021-05-21 09:22:54 +08:00
"Redis Key 不需要修改", 应用层面可以这么说……但是 redis 内部进行管理的话,应该不是, 比如 dict 进行 rehash
GrayXu
2021-05-21 10:29:19 +08:00
因为 redis key 并不是不需要修改的。
jay1002008
2021-05-21 12:14:49 +08:00
@GrayXu 比如哪个场景?请教
jay1002008
2021-05-21 12:15:30 +08:00
@ebingtel dict rehash 的时候,key 也需要 update 吗?是哪个步骤呢?请教下哈
ebingtel
2021-05-21 13:44:37 +08:00
@jay1002008 不是说要改 而是说在不改的情况下,用到你原文提到的 sds 优势……比如 dict.c 里面:compareCallback 的函数 你可以看看
ebingtel
2021-05-21 13:46:23 +08:00
@jay1002008 或者在源码里面 搜一下 sds 之类的关键字 就能看到很多场景需要了
ruanimal
2021-05-21 15:19:06 +08:00
因为 sds 的内存是复用的,也就是需要修改
jay1002008
2021-05-21 16:32:10 +08:00
@ebingtel
看了下 dict.c 中 compareCallback 函数,具体如下:

int compareCallback(void *privdata, const void *key1, const void *key2) {
int l1,l2;
DICT_NOTUSED(privdata);

l1 = strlen((char*)key1);
l2 = strlen((char*)key2);
if (l1 != l2) return 0;
return memcmp(key1, key2, l1) == 0;
}

里面用到了 strlen 和 memcmp 两个 C 函数,sds 可以支持,但 c 字符串也可以支持,所以还是不太理解这个场景。

另外,sds 使用的场景确实有,但 key 使用 sds 的必要场景,感觉还是没有见到。
jay1002008
2021-05-21 16:33:55 +08:00
@ruanimal
我的问题是:redis 存储键值对,Key 也使用 sds,感觉没啥必要。--!
ebingtel
2021-05-21 17:51:04 +08:00
@jay1002008 咱俩的版本不一样:

int compareCallback(void *privdata, const void *key1, const void *key2) {
int l1,l2;
DICT_NOTUSED(privdata);

l1 = sdslen((sds)key1);
l2 = sdslen((sds)key2);
if (l1 != l2) return 0;
return memcmp(key1, key2, l1) == 0;
}
……
sanggao
2021-05-21 18:38:56 +08:00
redis 有 rename 这个函数啊,这个就是供用户修改 key 的
jay1002008
2021-05-21 19:26:32 +08:00
@ebingtel
呃。好像是的呢。不过看到你的版本,我理解了。
jay1002008
2021-05-21 19:27:10 +08:00
@sanggao
哦,是的呢,都不记得有这个命令了。rename 的时候,这个似乎最方便了。
3Q
ruanimal
2021-05-24 09:54:34 +08:00
@jay1002008 因为 sds 不只是 key 在用, 内部所以用到字符串的地方基本都是用的 sds,你看下源码就知知道了
jay1002008
2021-05-24 10:25:39 +08:00
@ruanimal 可能我没有表达清楚,我的问题是:为什么 key 也使用 sds,而不是“内部用到字符串的地方”为什么使用 sds 。
问题的解答 @sanggao 举的例子最体验了直接原因哈。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/778248

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX