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