【一天一个知识点系列】- Redis之集群倾斜
集群倾斜
概念
- 集群倾斜指不同节点之间数据量和请求量出现明显差异, 这种情况将加大负载均衡和开发运维的难度
分类
- 数据倾斜
- 节点和槽分配严重不均
- 定位:针对每个节点分配的槽不均的情况,可以使用
redis-trib.rb info{host: ip}进行定位
- 解决:当节点对应槽数量不均匀时,可以使用
redis-trib.rb rebalance命令进行平衡
- 不同槽对应键数量差异过大
- 产生原因: 键通过
CRC16哈希函数映射到槽上,正常情况下槽内键数量会相对均匀。 但当大量使用hash_tag时, 会产生不同的键映射到同一个槽的情况。 特别是选择作为hash_tag的数据离散度较差时,将加速槽内键数量倾斜情况
- 定位:通过命令:
cluster countkeysinslot{slot}可以获取槽对应的键数量,识别出哪些槽映射了过多的键,再通过命令cluster getkeysinslot{slot}{count}循环迭代出槽下所有的键,从而发现过度使用hash_tag的键
- 解决:使用
hash_tag的数据离散度较好的
- 集合对象包含大量元素
- 定位:对于大集合对象的识别可以使用
redis-cli--bigkeys命令识别
- 解决:找出大集合之后可以根据业务场景进行拆分。 同时集群槽数据迁移是对键
migrate操作完成,过大的键集合如几百兆,容易造成migrate命令超时导致数据迁移失败
- 内存相关配置不一致
- 产生原因:内存相关配置指
hash-max-ziplist-value、setmax-intset-entries等压缩数据结构配置。 当集群大量使用hash、set等数据结构时,如果内存压缩数据结构配置不一致, 极端情况下会相差数倍的内存, 从而造成节点内存量倾斜
- 解决:内存压缩数据结构配置保持一致
- 请求倾斜
- 产生原因: 集群内特定节点请求量/流量过大将导致节点之间负载不均, 影响集群均衡和运维成本。 常出现在热点键场景, 当键命令消耗较低时如小对象的
get、 set、 incr等, 即使请求量差异较大一般也不会产生负载严重不均。 但是当热点键对应高算法复杂度的命令或者是大对象操作如hgetall、 smembers等, 会导致对应节点负载过高的情况
- 解决方案
- 合理设计键,热点大集合对象做拆分或使用
hmget替代hgetall避免整体读取
- 不要使用热键作为
hash_tag, 避免映射到同一槽。
- 对于一致性要求不高的场景, 客户端可使用本地缓存减少热键调用