Redis 中 Key 为什么也使用 SDS 而不是 C 字符串呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jay1002008
V2EX    Redis

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

  •  
  •   jay1002008 2021-05-21 00:18:46 +08:00 3493 次点击
    这是一个创建于 1605 天前的主题,其中的信息可能已经有所发展或是发生改变。

    SDS 类型具有几大优势:

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

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

    16 条回复    2021-05-24 10:25:39 +08:00
    CEBBCAT
        1
    CEBBCAT  
       2021-05-21 00:33:02 +08:00
    我个人觉得,二进制安全就已经很诱人了。另外搜到一篇博客,一起贴上来:

    https://redisbook.readthedocs.io/en/latest/internal-datastruct/sds.html
    ebingtel
        2
    ebingtel  
       2021-05-21 09:22:54 +08:00
    "Redis Key 不需要修改", 应用层面可以这么说……但是 redis 内部进行管理的话,应该不是, 比如 dict 进行 rehash
    GrayXu
        3
    GrayXu  
       2021-05-21 10:29:19 +08:00
    因为 redis key 并不是不需要修改的。
    jay1002008
        4
    jay1002008  
    OP
       2021-05-21 12:14:49 +08:00
    @GrayXu 比如哪个场景?请教
    jay1002008
        5
    jay1002008  
    OP
       2021-05-21 12:15:30 +08:00
    @ebingtel dict rehash 的时候,key 也需要 update 吗?是哪个步骤呢?请教下哈
    ebingtel
        6
    ebingtel  
       2021-05-21 13:44:37 +08:00
    @jay1002008 不是说要改 而是说在不改的情况下,用到你原文提到的 sds 优势……比如 dict.c 里面:compareCallback 的函数 你可以看看
    ebingtel
        7
    ebingtel  
       2021-05-21 13:46:23 +08:00
    @jay1002008 或者在源码里面 搜一下 sds 之类的关键字 就能看到很多场景需要了
    ruanimal
        8
    ruanimal  
       2021-05-21 15:19:06 +08:00
    因为 sds 的内存是复用的,也就是需要修改
    jay1002008
        9
    jay1002008  
    OP
       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
        10
    jay1002008  
    OP
       2021-05-21 16:33:55 +08:00
    @ruanimal
    我的问题是:redis 存储键值对,Key 也使用 sds,感觉没啥必要。--!
    ebingtel
        11
    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
        12
    sanggao  
       2021-05-21 18:38:56 +08:00
    redis 有 rename 这个函数啊,这个就是供用户修改 key 的
    jay1002008
        13
    jay1002008  
    OP
       2021-05-21 19:26:32 +08:00
    @ebingtel
    呃。好像是的呢。不过看到你的版本,我理解了。
    jay1002008
        14
    jay1002008  
    OP
       2021-05-21 19:27:10 +08:00
    @sanggao
    哦,是的呢,都不记得有这个命令了。rename 的时候,这个似乎最方便了。
    3Q
    ruanimal
        15
    ruanimal  
       2021-05-24 09:54:34 +08:00
    @jay1002008 因为 sds 不只是 key 在用, 内部所以用到字符串的地方基本都是用的 sds,你看下源码就知知道了
    jay1002008
        16
    jay1002008  
    OP
       2021-05-24 10:25:39 +08:00
    @ruanimal 可能我没有表达清楚,我的问题是:为什么 key 也使用 sds,而不是“内部用到字符串的地方”为什么使用 sds 。
    问题的解答 @sanggao 举的例子最体验了直接原因哈。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2719 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 12:10 PVG 20:10 LAX 05:10 JFK 08:10
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86