问题描述:redis cluter 集群中有一个节点 xxx:6380 内存使用 100%, 其他节点使用内存均在 20%左右,导致业务方报 OOM 错误。 求解疑问:为什么节点 xxx:6380 maxmemory-policy 设置为 allkeys-lru,在内存使用到 100%时,客户端会报‘ OOM ’(正常 redis 会删除 key 释放内存,而且在我的 cluster 环境中测试使用 Python 测试并没报‘ OOM ’)?
1
janezhang OP 有没有搞 Android 或者 IOS 的同学,可以一起探讨一下[可怜]
|
2
gouchaoer 2017-05-27 11:08:04 +08:00 via Android
codis 用的更多?
|
3
yuzunzhi 2017-05-27 11:17:37 +08:00
你是如何判断 XXX:6380 节点的内存使用 100%,是 redis 应用把所有内存用光的?
如果是 redis cluster,默认所有的 hash 槽会平均分布在所有主节点上,你确定所有主节点的机器配置是统一的吗? 你所说的业务方的业务是否跑在了 XXX:6380 这个节点所在的机器上? |
4
Mirana 2017-05-27 11:31:16 +08:00
可能是 maxmemory 配的太小了?
|
5
janezhang OP @yuzunzhi
1、本来以为是业务方的应用问题,后来从 aof 文件汇分析并没有明显问题,基本排除和业务无关。 2、集群各个服务器硬件、redis 版本配置均相同(配置除了一些状态值等有区别),另外通过 client list 收集各个节点客户端 ip 地址统计,也没发现只连接 xxx:6380 的客户端。 |
8
Mirana 2017-05-27 11:51:31 +08:00
|
11
soli 2017-05-27 14:43:32 +08:00
看一下请求最多的是哪个 key ?
|
12
wellsc 2017-05-27 15:00:08 +08:00
|
13
janezhang OP @soli 看过了 key 没什么问题。有一个比较诡异的地方是 key 操作:在业务代码中没有使用 RPUSH 代码,用的是 LPUSH
|
14
tomatoz 2017-05-28 01:39:58 +08:00
有一种可能是 key 设计的时候使用了 hash tag
比如{user102}:first.name 和 {user102}:last.name 这两个 key,在计算 hash 的时候只会对大括号里里面的部分进行计算,所以它们肯定会分配到同一节点,即使 key 不一样。 |
15
woshixiaohao1982 2017-05-28 07:58:04 +08:00 via iPhone
@tomatoz 前缀 hash ?
|
16
tomatoz 2017-05-28 10:07:07 +08:00 via Android
@woshixiaohao1982 不是前缀,是如果键名中包含大括号,而且大括号之间至少有一个字符,那么{}之间的内容就是参与 hash 计算的有效部分,如过不满足上述条件,整个键名就是参与 hash 的有效部分。
|
17
woshixiaohao1982 2017-05-28 11:54:17 +08:00
@tomatoz ok 我没读过 redis 的文档,,原来还有这一出,,很有可能 hash 全部集中到一个 redis 实例上的 hash 槽了吧
官方的文档是多少个槽 根据从实例个数,然后分配槽,貌似主 redis 会 fork() 自动转发 key 的请求到 对应的 redis 实例上 |
18
woshixiaohao1982 2017-05-28 11:54:54 +08:00
@tomatoz 不知道 windows 上面的 fork()实现 跟 linux 是不是一样 写时拷贝
|
19
liu7833 2017-05-28 21:48:24 +08:00
打个内存 dump,分析各个节点 key 的数量和内存占用量,排除数据的 hash 不均匀。换了 python 没这情况可能是没业务的量级,当然更可能的是业务代码的问题
|
20
janezhang OP |
21
yatesun 2017-06-29 11:32:42 +08:00
我遇到过流量大了之后很卡,不知道是不是网卡问题,一天的请求量可能有 1 亿多
|
22
yatesun 2017-06-29 11:33:28 +08:00
client 是 php,试过短连接和长连接,timeout 之类的也处理了,但是还是有问题。
|