问题:出现OOM报错: OOM command not allowed when used memory > ‘maxmemory’,部分ECS应用程序无法向db写入,set t2 s2 OOM:
Redis 5.0 cluster集群 4G内存
DCS网段:192.168.1.0/24
分片1:master 192.168.1.12 slave 192.168.1.37
分片2:master 192.168.1.10 slave 192.168.1.69
分片3:master 192.168.1.26 slave 192.168.1.134
分析思路:
一、查监控
1、Redis集群内存占用46.97%,无明显异常
2、查节点内存监控。分片2中master达到100%,其余20
二、大KEY分析
工具分析:华为dcs,redis-cli -h IP -p port –bigkeys命令,列出各个类型数据中最大Key
也可用离线方式:rdb_bigkeys分析工具,对rdb文件进行分析
string类型的大key为“nc_filed/_pk”,大小为13283byte,list、set、hash、zset类型的数据未发现大key。
三、大key解决
先重启,确定不是本地缓存。本次因为大KEY大小分布不均匀,某个达到maxmemory。
1、临时方案:删除(非字符串的bigkey,不用 del 删除,用 hscan、sscan、zscan 方式渐进式删除)
2、长期方案
1)拆分,变成value1,value2… valueN,打散到不同分片中
newkey = key + string.valueof(hash(field)%10000)
以hash为例:
将原hget、hset方法改成(加入固定hash桶数量为10000),先计算field的hash值模取10000,确定该field在哪个key上
将大key均匀分割,对field进行hash并通过质数N取余,余数加key上,质数N为997,新key设置为:
newKey = order_20200102_String.valueOf( Math.abs(order_id.hashcode() % 997) )
field = order_id
value = 10
hset (newKey, field, value) ;
hget(newKey, field)
2)改存ID,其他去db。
3)序列化手段压缩,或存md5(加密),时间换空间。
3、预防
1) 配置监控:节点上、CPU利用率、入/出网最大带宽
2) 控制大小:string < 10KB以内,其他元素个数<5000
3) 定期用工具检查
四、大key危害
1.内存不均:节点间内存不均匀,间接地影响key负载不均匀
2.阻塞请求:redis单线程,单大value读写长,阻塞后续
3.阻塞网络:单value占网卡带宽,影响该服务器上其他
https://www.jianshu.com/p/88d22ae7704e