Redis.7 集群运维
Redis 集群由于自身的分布式特性,相比单机场景在开发和运维方面存在一些差异。
Redis.7.1 集群完整性
为了保证集群完整性,默认情况下当集群 16384 个槽任何一个没有指派到节点时整个集群不可用。执行任何键命令返回(error)CLUSTERDOWN Hash slot not served 错误。这是对集群完整性的一种保护措施,保证所有的槽都指派给在线的节点。但是当持有槽的主节点下线时,从故障发现到自动完成转移期间整个集群是不可用状态,对于大多数业务无法容忍这种情况,因此建议将参数cluster-require-full-coverage 配置为 no,当主节点故障时只影响它负责槽的相关命令执行,不会影响其他主节点的可用性。
Redis.7.2 带宽消耗
集群内 Gossip 消息通信本身会消耗带宽,官方建议集群最大规模在 1000 以
内,也是出于对消息通信成本的考虑,因此单集群不适合部署超大规模的节
点。在之前节点通信小节介绍到,集群内所有节点通过 ping/pong 消息彼此交换信息,节点间消息通信对带宽的消耗体现在以下几个方面:
·消息发送频率:跟 cluster-node-timeout 密切相关,当节点发现与其他节点最后通信时间超过 cluster-node-timeout/2 时会直接发送 ping 消息。
·消息数据量:每个消息主要的数据占用包含:slots 槽数组(2KB 空间)和整个集群 1/10 的状态数据(10 个节点状态数据约 1KB)。
·节点部署的机器规模:机器带宽的上线是固定的,因此相同规模的集群分布的机器越多每台机器划分的节点越均匀,则集群内整体的可用带宽越高。
例如,一个总节点数为 200 的 Redis 集群,部署在 20 台物理机上每台划分 10个节点,cluster-node-timeout 采用默认 15 秒,这时 ping/pong 消息占用带宽达到 25Mb。如果把 cluster-node-timeout 设为 20,对带宽的消耗降低到15Mb 以下。
集群带宽消耗主要分为:读写命令消耗 Gossip 消息消耗。因此搭建 Redis 集群时需要根据业务数据规模和消息通信成本做出合理规划:
1)在满足业务需要的情况下尽量避免大集群。同一个系统可以针对不同业务场景拆分使用多套集群。这样每个集群既满足伸缩性和故障转移要求,还可以规避大规模集群的弊端。我在网上看到的一个推荐系统,根据数据特征使用了 5个 Redis 集群,每个集群节点规模控制在 100 以内。
2)适度提高 cluster-node-timeout 降低消息发送频率,同时 cluster-nodetimeout 还影响故障转移的速度,因此需要根据自身业务场景兼顾二者的平衡。
3)如果条件允许集群尽量均匀部署在更多机器上。避免集中部署,如集群有
60 个节点,集中部署在 3 台机器上每台部署 20 个节点,这时机器带宽消耗将非常严重。
Redis.7.3 Pub/Sub 广播问题
Redis 在 2.0 版本提供了 Pub/Sub(发布/订阅)功能,用于针对频道实现消息的发布和订阅。但是在集群模式下内部实现对所有的 publish 命令都会向所有的节点进行广播,造成每条 publish 数据都会在集群内所有节点传播一次,加重带宽负担
通过命令演示 Pub/Sub 广播问题:
1)对集群所有主从节点执行 subscribe 命令订阅 cluster_pub_spread 频道,用于验证集群是否广播消息:
127.0.0.1:6379> subscribe cluster_pub_spread
127.0.0.1:6380> subscribe cluster_pub_spread
127.0.0.1:6382> subscribe cluster_pub_spread
127.0.0.1:6383> subscribe cluster_pub_spread
127.0.0.1:6385> subscribe cluster_pub_spread
127.0.0.1:6386> subscribe cluster_pub_spread
2)在 6379 节点上发布频道为 cluster_pub_spread 的消息:
127.0.0.1:6379> publish cluster_pub_spread message_body_1
3)集群内所有的节点订阅客户端全部收到了消息:
127.0.0.1:6380> subscribe cluster_pub_spread
1) "message"
2) "cluster_pub_spread"
3) "message_body_1
127.0.0.1:6382> subscribe cluster_pub_spread
1) "message"
2) "cluster_pub_spread"
3) "message_body_1
...
针对集群模式下 publish 广播问题,需要引起开发人员注意,当频繁应用
Pub/Sub 功能时应该避免在大量节点的集群内使用,否则会严重消耗集群内网络带宽。针对这种情况建议使用 sentinel 结构专门用于 Pub/Sub 功能,从而规避这一问题。