Redis.7.4 集群倾斜
集群倾斜指不同节点之间数据量和请求量出现明显差异,这种情况将加大负载均衡和
开发运维的难度。因此需要理解哪些原因会造成集群倾斜,从而避免这一问题。
1.数据倾斜
数据倾斜主要分为以下几种:
·节点和槽分配严重不均。
·不同槽对应键数量差异过大。
·集合对象包含大量元素。
·内存相关配置不一致。
1)节点和槽分配严重不均。针对每个节点分配的槽不均的情况,可以使用 redistrib.rb info{host:ip}进行定位,命令如下:
#redis-trib.rb info 127.0.0.1:6379
127.0.0.1:6379 (cfb28ef1...) -> 33348 keys | 5461 slots | 1 slaves.
127.0.0.1:6380 (8e41673d...) -> 33391 keys | 5461 slots | 1 slaves.
127.0.0.1:6386 (475528b1...) -> 33263 keys | 5462 slots | 1 slaves.
[OK] 100002 keys in 3 masters.
6.10 keys per slot on average.
以上信息列举出每个节点负责的槽和键总量以及每个槽平均键数量。当节点对应槽数量不均匀时,可以使用 redis-trib.rb rebalance 命令进行平衡:
#redis-trib.rb rebalance 127.0.0.1:6379
...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.0% threshold.
2)不同槽对应键数量差异过大。键通过 CRC16 哈希函数映射到槽上,正常情况下槽内键数量会相对均匀。但当大量使用 hash_tag 时,会产生不同的键映射到同一个槽的情况。特别是选择作为 hash_tag 的数据离散度较差时,将加速槽内键数量倾斜情况。通过命令:cluster countkeysinslot{slot}可以获取槽对应的键数量,识别出哪些槽映射了过多的键。再通过命令 cluster
getkeysinslot{slot}{count}循环迭代出槽下所有的键。从而发现过度使用
hash_tag 的键。
3)集合对象包含大量元素。对于大集合对象的识别可以使用 redis-cli--bigkeys
命令识别,具体使用见 12.5 节。找出大集合之后可以根据业务场景进行拆分。同时集群槽数据迁移是对键执行 migrate 操作完成,过大的键集合如几百兆,容易造成 migrate 命令超时导致数据迁移失败。
4)内存相关配置不一致。内存相关配置指 hash-max-ziplist-value、set-maxintset-entries 等压缩数据结构配置。当集群大量使用 hash、set 等数据结构时,如果内存压缩数据结构配置不一致,极端情况下会相差数倍的内存,从而造成节点内存量倾斜。
2.请求倾斜
集群内特定节点请求量/流量过大将导致节点之间负载不均,影响集群均衡和运维成本。常出现在热点键场景,当键命令消耗较低时如小对象的 get、set、incr等,即使请求量差异较大一般也不会产生负载严重不均。但是当热点键对应高算法复杂度的命令或者是大对象操作如 hgetall、smembers 等,会导致对应节点负载过高的情况。避免方式如下:
1)合理设计键,热点大集合对象做拆分或使用 hmget 替代 hgetall 避免整体读取。
2)不要使用热键作为 hash_tag,避免映射到同一槽。
3)对于一致性要求不高的场景,客户端可使用本地缓存减少热键调用。