一个 key 大约 1M 的话,读取性能会退化成几十毫秒,如果 1k 的话只有几毫秒,按道理说读取内存性能很高的呀,为什么退化的这么严重
|  |      1codehz      2020-10-20 15:59:46 +08:00 (你是不是没考虑到网络传输 | 
|      2BoarBoar      2020-10-20 16:40:15 +08:00 不负责任猜测,是因为 key 过大的话在内存中分配成不连续地址了,从数组变成了链表 | 
|  |      3Narcissu5      2020-10-20 17:04:28 +08:00 redis 要首先针对 key 计算 hash,如果 hash 冲突了还得比较,估计慢在这里了 | 
|  |      4caola      2020-10-20 17:09:22 +08:00 key 搞那长?还不如转为短的 key,再把完整的内容放到 hash 表里 | 
|  |      5justseemore      2020-10-20 17:10:10 +08:00 | 
|  |      6noble4cc OP @codehz 本机测试的,网络传输忽略,网络传输确实会,大了 tcp 要分好几个包,但是我觉得这不是根本原因,就算把测试 key 缩小为 1.5k ,一个包可以传输,1.5k 的 key 耗时涨的也挺过分的,好几毫秒的 get 请求不正常 | 
|      8kerro1990      2020-10-20 18:56:16 +08:00 1M 内存质量不行的话,寻址都会废 | 
|  |      94771314      2020-10-20 19:12:26 +08:00 寻址慢吧 | 
|  |      10zeroday      2020-10-20 19:15:20 +08:00 总要遍历一遍把 value 取出来吧...你 key 越大遍历的越久,能不慢吗... | 
|      11Jooooooooo      2020-10-20 19:15:34 +08:00 卡在网卡上了 | 
|  |      12gitgabige      2020-10-20 19:16:45 +08:00 1M 大的 key ??? | 
|      13katsusan      2020-10-20 19:24:41 +08:00 via iPhone 用户态内存复制到内核缓冲区吧,另外 ram 的存取不命中 cache 的话本来也不快,大概要六七十纳秒起步。 | 
|  |      14scriptB0y      2020-10-20 19:30:23 +08:00 感觉是楼上说的内存寻址的问题…… 可以考虑使用 https://redis.io/commands/unlink 命令删除,这个是立即返回的。 | 
|  |      15la2la      2020-10-20 19:37:01 +08:00 @scriptB0y 抱歉,没有必要替极客时间推广,只是提供一种排查思路,因为可能造成这个问题的原因有很多,从服务器性能到网络 IO 都有可能,正好最近在看这个东西还不错就提了一下。已删除图片链接 | 
|      17laminux29      2020-10-20 21:15:02 +08:00 这种有源码的东西,直接调试一下不就知道原因了,上面一堆人瞎猜我也是醉了,这种事情能猜准? | 
|      18Mirana      2020-10-20 22:44:49 +08:00 1. redisdb 本身就是个大哈希表,读取和插入都要对 key 做一次哈希找到对应的 slot,对 1m 数据做哈希和 1k 数据做哈希有性能差别 2. 网络耗时增加 | 
|      19FutherAll      2020-10-20 23:19:49 +08:00 via iPhone 大 key 问题指的是 key 对应的 value 大,为什么这么多说 key 大的,key 如果到 kb 级别,感觉是 key 的设计有问题。 value 过大,比如 string 到 100KB 这种,其它容器类的比如 list zset 元素个数过多,读取和写入就会耗费大量内存和 CPU,阻塞其它操作;集群模式的话单个节点很容易压力多大。再叠加热 key 之类的,节点很容易就被打崩了。 | 
|  |      20u2r1Hqo6HExmNsrt      2020-10-21 09:24:27 +08:00 @laminux29 具体怎么做?自己加 log 编译一个版本出来调试?还是直接编译+断点调试? | 
|      22wiewiewie      2020-10-21 14:04:32 +08:00 redis 6 呢? | 
|  |      23salaryfly      2020-10-21 16:04:54 +08:00 简短的说一下: 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 |