• 请不要在回答技术问题时复制粘贴 AI 生成的内容
noble4cc
V2EX  ›  程序员

redis 大 key 导致读取和删除性能降低的原因是什么呢?

  •  
  •   noble4cc · Oct 20, 2020 · 4644 views
    This topic created in 2211 days ago, the information mentioned may be changed or developed.

    一个 key 大约 1M 的话,读取性能会退化成几十毫秒,如果 1k 的话只有几毫秒,按道理说读取内存性能很高的呀,为什么退化的这么严重

    23 replies  •  2020-10-21 16:04:54 +08:00
    codehz
    codehz
    Oct 20, 2020
    1
    (你是不是没考虑到网络传输
    BoarBoar
    BoarBoar
    Oct 20, 2020
    2
    不负责任猜测,是因为 key 过大的话在内存中分配成不连续地址了,从数组变成了链表
    Narcissu5
    Narcissu5
    Oct 20, 2020
    3
    redis 要首先针对 key 计算 hash,如果 hash 冲突了还得比较,估计慢在这里了
    caola
    caola
    Oct 20, 2020
    4
    key 搞那长?还不如转为短的 key,再把完整的内容放到 hash 表里
    justseemore
    justseemore
    Oct 20, 2020
    5
    我感觉也是网络因素..
    noble4cc
    noble4cc
    OP
    Oct 20, 2020
    6
    @codehz 本机测试的,网络传输忽略,网络传输确实会,大了 tcp 要分好几个包,但是我觉得这不是根本原因,就算把测试 key 缩小为 1.5k ,一个包可以传输,1.5k 的 key 耗时涨的也挺过分的,好几毫秒的 get 请求不正常
    noble4cc
    noble4cc
    OP
    Oct 20, 2020
    7
    @caola 不是 key 是,key 对应的 value
    kerro1990
    kerro1990
    Oct 20, 2020
    8
    1M 内存质量不行的话,寻址都会废
    4771314
    4771314
    Oct 20, 2020
    9
    寻址慢吧
    zeroday
    zeroday
    Oct 20, 2020
    10
    总要遍历一遍把 value 取出来吧...你 key 越大遍历的越久,能不慢吗...
    Jooooooooo
    Jooooooooo
    Oct 20, 2020
    11
    卡在网卡上了
    gitgabige
    gitgabige
    Oct 20, 2020
    12
    1M 大的 key ???
    katsusan
    katsusan
    Oct 20, 2020 via iPhone
    13
    用户态内存复制到内核缓冲区吧,另外 ram 的存取不命中 cache 的话本来也不快,大概要六七十纳秒起步。
    scriptB0y
    scriptB0y
    Oct 20, 2020
    14
    感觉是楼上说的内存寻址的问题…… 可以考虑使用 https://redis.io/commands/unlink 命令删除,这个是立即返回的。
    la2la
    la2la
    Oct 20, 2020
    15
    @scriptB0y 抱歉,没有必要替极客时间推广,只是提供一种排查思路,因为可能造成这个问题的原因有很多,从服务器性能到网络 IO 都有可能,正好最近在看这个东西还不错就提了一下。已删除图片链接
    noble4cc
    noble4cc
    OP
    Oct 20, 2020
    16
    @zeroday 字符串为什么要遍历
    laminux29
    laminux29
    Oct 20, 2020
    17
    这种有源码的东西,直接调试一下不就知道原因了,上面一堆人瞎猜我也是醉了,这种事情能猜准?
    Mirana
    Mirana
    Oct 20, 2020
    18
    1. redisdb 本身就是个大哈希表,读取和插入都要对 key 做一次哈希找到对应的 slot,对 1m 数据做哈希和 1k 数据做哈希有性能差别
    2. 网络耗时增加
    FutherAll
    FutherAll
    Oct 20, 2020 via iPhone
    19
    大 key 问题指的是 key 对应的 value 大,为什么这么多说 key 大的,key 如果到 kb 级别,感觉是 key 的设计有问题。

    value 过大,比如 string 到 100KB 这种,其它容器类的比如 list zset 元素个数过多,读取和写入就会耗费大量内存和 CPU,阻塞其它操作;集群模式的话单个节点很容易压力多大。再叠加热 key 之类的,节点很容易就被打崩了。
    u2r1Hqo6HExmNsrt
    u2r1Hqo6HExmNsrt
    Oct 21, 2020
    20
    @laminux29 具体怎么做?自己加 log 编译一个版本出来调试?还是直接编译+断点调试?
    noble4cc
    noble4cc
    OP
    Oct 21, 2020
    21
    @Mirana 是 key 对应的 value 大,一般 key 不会多大
    wiewiewie
    wiewiewie
    Oct 21, 2020
    22
    redis 6 呢?
    salaryfly
    salaryfly
    Oct 21, 2020
    23
    简短的说一下:
    1. 如果有大 key 存在,那么在进行复杂度为 O(n)的操作时,耗时会线性增长。
    2. Redis 被设计为基于单线程模型,这意味着某些高耗时操作会导致整体服务操作超时。

    一个很典型的例子就是 DEL 和 UNLINK, DEL 是 O(n)的阻塞操作,会导致耗时过高;而 UNILINK 是 O(1)的操作,基本不会有超时情况。两者的主要区别是 UNLINK 用后台线程处理需要删除的数据的内存释放。从这一点也可以看出,删除大 Key 的超时是因为镜像内存释放操作的原因。

    antirez:Redis is very fast as long as you use O(1) and O(log_N) commands.

    PS. 如果对这个问题有更深的兴趣或者想讨论一些技术问题,
    欢迎关注公众号留言交流: Salaryfly
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2451 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 63ms · UTC 12:19 · PVG 20:19 · LAX 04:19 · JFK 07:19
    ♥ Do have faith in what you're doing.