前言
Redis除了通过主从和sentinel来保证集群的高可用,还可以使用redis cluster实现服务的高可用。
一、Redis cluster介绍
- Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。
- Redis 集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误。
- Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令。
Cluster自动分割数据到不同的节点上。整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽。
二、Redis Cluster部署
1.基础配置
Redis集群至少需要三个master节点,并且推荐节点数为奇数。
因为新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,当其中一个挂了,是达不到选举新master的条件的。
奇数个master节点可以在满足选举该条件的基础上节省一个节点,比如三个master节点和四个master节点的集群相比,大家如果都挂了一个master节点都能选举新master节点,如果都挂了两个master节点都没法选举新master节点了,所以奇数的master节点更多的是从节省机器资源角度出发说的。
Redis Cluster端口
每个 Redis 集群节点都需要两个开放的 TCP 连接:一个用于为客户端提供服务的 Redis TCP 端口(例如 6379)和第二个称为集群总线端口的端口。 默认情况下,集群总线端口是通过在数据端口上加 10000 来设置的(例如,16379);可以在配置cluster-port中覆盖此设置。
集群总线是使用二进制协议的节点间通信通道,由于 带宽和处理时间少。 节点使用群集总线进行故障检测、配置更新、故障转移授权等。 客户端不应尝试与群集总线端口通信,而应使用 Redis 命令端口。
配置文件
cluster-enabled yes/no
yes表示启用redis cluser,no表示不启用,以 standalone 方式运行。
cluster-config-file filename
存储redis集群运行的相关信息,但这不是用户可编辑的配置文件,而是 Redis 集群节点在每次发生更改时自动保留集群配置(基本上是状态)的文件,以便能够在启动时重新读取它。该文件列出了群集中的其他节点、其状态、持久变量等内容。通常,由于某些消息接收,此文件会在磁盘上重写和刷新。
cluster-node-timeout milliseconds
redis 集群节点不可用且不被视为失败的最长时间。如果无法访问主节点的时间超过指定的时间,则其副本将对其进行故障转移。此参数控制 Redis 集群中的其他重要内容。值得注意的是,在指定时间内无法访问大多数主节点的每个节点都将停止接受查询。
cluster-slave-validity-factor factor
如果设置为0,则副本将始终认为自己有效,因此将始终尝试故障转移主节点,而不管主节点和副本之间的链路断开多长时间。如果该值为正,则最大断开连接时间的计算方法是节点超时值乘以此选项提供的因子,如果节点是副本,则当主链路断开连接超过指定的时间量时,它不会尝试启动故障转移。例如,如果节点超时设置为 5 秒,有效性因子设置为 10,则与主节点断开连接超过 50 秒的副本将不会尝试故障转移其主节点。请注意,如果没有能够故障转移的副本,则任何大于零的值都可能导致 Redis 集群在主故障后不可用。在这种情况下,仅当原始主节点重新加入集群时,集群才会恢复可用。
cluster-migration-barrier count
一个主副本将保持连接的最小副本数,以便另一个副本迁移到一个不再被任何副本覆盖的主副本。
cluster-require-full-coverage yes/no
如果设置为yes,就像默认情况一样,如果某个百分比的关键空间没有被任何节点覆盖,集群将停止接受写操作。如果将该选项设置为no,则即使只能处理关于键的子集的请求,集群仍将为查询提供服务。
表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用,如果为yes则集群不可用。
cluster-allow-reads-when-down yes/no
如果设置为否(默认情况下),则当集群标记为失败时,当节点无法达到主节点的仲裁或未达到完全覆盖时,Redis 集群中的节点将停止为所有流量提供服务。这可以防止从不知道群集中更改的节点读取可能不一致的数据。此选项可以设置为 yes 以允许在失败状态期间从节点读取,这对于希望优先考虑读取可用性但仍希望防止不一致写入的应用程序非常有用。当使用只有一个或两个分片的 Redis 集群时,它也可以用于,因为它允许节点在主节点发生故障但无法自动故障转移时继续提供写入服务。
2.安装部署
安装文档适用于Redis5.0以后版本
从redis5.0后;不再使用ruby搭建集群;修改为使用redis-cli
配置文件
#cluster相关参数,Redis其他参数请参照Redis相关配置
cluster-enabled yes #开启集群
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
cluster-require-full-coverage no
appendonly yes #持久化
启动端口7000-7005的6个Redis实例
执行集群初始化操作:
>redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1
在出现提示框后输入yes
>yes
这里使用的命令是 create,因为我们想创建一个新的集群。 该选项意味着我们希望为每个创建的主节点提供一个副本。–cluster-replicas 1
每个Redis的节点都有一个ID值,此ID将被此特定redis实例永久使用,以便实例在集群上下文中具有唯一的名称。 每个节点都会记住使用此ID的每个其他节点,而不是通过IP或端口。IP地址和端口可能会发生变化,但唯一的节点标识符在节点的整个生命周期内都不会改变。 我们简单地称这个标识符为节点ID。在Create集群时;一定要使用外网IP。避免外部连接时返回的是127.0.0.1而连接错误
如果部署时提示gcc版本较低,需要使用gcc4.9以上版本
升级GCC
# yum -y install gcc tcl
# yum -y install centos-release-scl
# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
查看gcc版本:
# gcc -v
scl只是临时启用,退出shell后会恢复原系统gcc版本:
# scl enable devtoolset-9 bash
如下命令表示永久启用:
# echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile
查看gcc版本:
# gcc -v
命令介绍
–cluster-replicas 集群自动分配主从;
创建集群,–cluster-replicas 1代表3主3从。通过该方式创建的带有从节点的机器自动分配对应的主从节点,无法手动指定。
秒交互两种方式:
- echo “yes”|redis-cli --cluster create 10.0.0.101:6380 10.0.0.102:6380 10.0.0.103:6380 10.0.0.101:6381 10.0.0.102:6381 10.0.0.103:6381 --cluster-replicas 1
- redis-cli --cluster create 172.31.228.200:6379 172.31.228.201:6379 172.31.228.199:6379 -a 5gUfpN1wgQr5t$e^nutaxKQp --cluster-yes
手动指定
集群6个实例172.31.228.200:6379、172.31.228.201:6379、172.31.228.199:6379、172.31.228.200:6380、172.31.228.201:6380、 172.31.228.199:6380,其中172.31.228.200:6379、172.31.228.201:6379、172.31.228.199:6379为master节点,172.31.228.200:6380、172.31.228.201:6380、 172.31.228.199:6380为从节点。集群密码为5gUfpN1wgQr5t$e^nutaxKQp。
redis-cli --cluster create 172.31.228.200:6379 172.31.228.201:6379 172.31.228.199:6379 -a 5gUfpN1wgQr5t$e^nutaxKQp --cluster-yes
redis-cli --cluster add-node 172.31.228.200:6380 172.31.228.200:6379 --cluster-slave --cluster-master-id 19c5b8deaf079ebb9832b6eefefa74c0c05a18b2 -a \'5gUfpN1wgQr5t$e^nutaxKQp\'
# 19c5b8deaf079ebb9832b6eefefa74c0c05a18b2为 172.31.228.200:6379的ID
redis-cli --cluster add-node 172.31.228.201:6380 172.31.228.201:6379 --cluster-slave --cluster-master-id 011326dd0ef2888e3ee8ed5590e5ee600dc96462 -a \'5gUfpN1wgQr5t$e^nutaxKQp\'
# 011326dd0ef2888e3ee8ed5590e5ee600dc96462为 172.31.228.201:6379 的ID
redis-cli --cluster add-node 172.31.228.199:6380 172.31.228.199:6379 --cluster-slave --cluster-master-id bfb1b52df455e9bbadeda19c16512f7378fd5e45 -a \'5gUfpN1wgQr5t$e^nutaxKQp\'
# bfb1b52df455e9bbadeda19c16512f7378fd5e45为172.31.228.199:6379 的ID
总结
Redis Cluster部署与维护较为便捷,因为可以自动内部实现服务异常时主从自动切换,一般只需要保证主节点拥有正常的从节点即可。
- 当某个从节点挂掉之后,对于redis集群来说几乎没有什么影响,相当于这个从节点对应的 主节点少了一个备份而已。
- 当某一个主节点挂掉之后,redis 会从这个 主节点 的 多个从节点中推选一个出来,担当master的工作,并且把之前依附在.
- 主节点的从节点调整依附到新的master上。如果新任的master也挂掉并且他没有从节点了,那么这个集群也真正的挂掉了。