Redis Cluster 搭建准备工作

  1. 搭建集群之前,务必有一点需要注意就是选举,因为在如今很多的分布式中间件里,集群都会有选举这个概念,一定要达到半数以上的节点,才能够发起公平的投票,否则就会脑裂,比如redis,zk,es等,所以至少保证3个master节点,master会发起选举投票的。这一点要须知。
  2. 配置6个节点的虚拟机(预先做好)

    • 192.168.1.221
    • 192.168.1.222
    • 192.168.1.223
    • 192.168.1.224
    • 192.168.1.225
    • 192.168.1.226
    • 192.168.1.227(新增Master)
    • 192.168.1.228(新增Slave)
  3. 每个节点搭建单机redis,清理aof和rdb文件(预先做好)
  4. 如果为单实例的Redis设置了密码password,那么每个节点都必须要设置masterauth,也就是对应密码,这样是为了master挂掉以后,对应的slave可以升级为master。
  5. 需要注意,选举的过程会短暂的对外不可用。

Redis Cluster 搭建实操演练

附:
关闭redis

./redis-cli -p <修改的端口号> -a <修改的密码> shutdown 

开启redis:

./redis-server redis.conf 

每个单实例中的 redis.conf 配置:

# 配置redis日志,便于检查
logfile /usr/local/redis/redis-221.log
 # 开启集群模式
cluster-enabled yes
# 每一个节点需要有一个配置文件,需要6份。每个节点处于集群的角色都需要告知其他所有节点,彼此知道,这个文件用于存储集群模式下的集群状态等信息,这个文件是由redis自己维护,我们不用管。如果你要重新创建集群,那么把这个文件删了就行
cluster-config-file nodes-221.conf
# 超时时间,超时则认为master宕机,随后主备切换
cluster-node-timeout 5000
# 开启AOF
appendonly yes 

创建集群,在任意节点运行如下命令一次:

#####
# 注意1:如果你使用的是redis3.x版本,需要使用redis-trib.rb来构建集群,最新版使用C语言来构建了,这个要注意
# 注意2:以下为新版的redis构建方式
#####

# 创建集群,主节点和从节点比例为1,1-3为主,4-6为从,这也是最经典用的最多的集群模式。cluster-replicas是几个slave,-a是执行秘密。
./redis-cli --cluster create ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6 --cluster-replicas 1 -a 123456 

-w1836
-w708

从上图中可以看到,slots槽,用于装数据,主节点有,从节点没有。

在任意节点查看集群信息:

./redis-cli --cluster check 192.168.1.221:6379 -a 123456 

查看主从状态信息:

./redis-cli -a 123456
info replication 

-w1077
-w1069

搭建集群时的日志

M221与S225
-w1845

M222与S226
-w1838

M223与S224
-w1833

从节点日志,主要进行复制:
-w1834

cluster nodes 查看各个节点的信息
-w1558

故障转移

如果一个master挂了,那么剩余的2个master会发起投票选举,从挂了的master对应的slave中选举出一个新的master,发生故障的master不会参与投票,这个要注意。

选举的时候需要半数以上的master都投票给同一个slave,那么他才会成为新的master。所以redis集群中至少需要3个主节点,2个是不行的。而且我们也是建议在不同的物理节点上去进行配置,如果是伪分布式集群,那么可能会有问题。

故障转移的主要流程首先是主观下线,然后是客观下线,这个我们在课程里有说过,要以客观为主,也就是半数以上的master都收不到某节点的心跳,则认为他宕机了,此时发起选举。

验证故障转移

  1. redis宕机,停止某一台master,观察日志,以及对应的从。
    -w1079
    上图中,225升级为master,原来的221下线。slots自动重新分配。
  2. 重启原来的221,可以发现,他加入到了225的麾下,成为他的slave,并且进行了主从数据同步。
    -w1839
    在新的主225中可以看到221的加入ask询问同步等信息
    -w1835
  3. 直接关闭225服务器,直接关停,相当于服务器炸了。测试后发现,221成为新的master,也就是说不论是redis宕机还是服务器炸了,对应的slave都能被选举为新的master,因为只要master集群客观认为你下线了,那么就会进行选举。

验证数据能否都在主从中获取

./redis-cli -a 123456 -c
 set name lee 

-w1093
集群中设值与取值,需要加-c
图中数据进入到了主222中,那么验证一下从某个从节点中能不能获取,他会跳转到222中去获取,因为现在是一个集群形态。
-w1108

如果不加-c,以单实例形式去操作,那么会报错。
-w1098

关闭主222,观察原来设置的数据,在slave226转变为master后,数据是否存在:
-w1071
因为数据会主从同步,所以master宕机后,slave中还是会有他的数据。这些数据都是跟着slot走的。

master宕机,他的slave升级为master,再次宕机,看看剩余的2主2从能否运行

紧接上面的,接着关闭新主226,剩余2主2从,查看状态,你会发现出错,提示说slots分配不均匀,因为有一对主从没有的slot都没了。
-w1094
随后在任意节点去查询数据,提示说当前集群不可用,我们需要恢复了。
-w1092

多master宕机数超过半数以上,集群不可用

同时有2个redis-master都宕机,那么无法达到半数以上,此时无法选举,当前集群不可用。由于速度比较快,虚拟机里难以演示,所以此处意会一下哈~
(如果半数以上 Master 处于关闭状态那么整个集群处于不可用状态。)

集群节点通信 gossip了解即可,无需深究

redis集群模式下的几个节点之间也会相互通信,他们的通信协议是gossip,各个节点之间会有ping pong等消息类型,每个节点也维护着redis的元数据,一旦发生更改会相互发送。

redis 水平扩容,增加节点,重新shard分配slot

新增192.168.1.227
修改redis.conf文件后,启动服务。查看分片信息:
-w862
对比现有的master
-w702
对比后他自己虽然标识master,但是没起作用,也没加入到现有的集群

这个时候需要使用如下命令,把节点加入到当前集群:

# 添加一个新的节点到现有的集群中。第一个ip为新节点,第二个ip为现有集群中的某个节点ip
新增192.168.1.227
./redis-cli --cluster add-node 192.168.1.227:6379 192.168.1.221:6379 -a 123456 

-w1100
如上图,新节点,加入成功。
-w1162
这个时候新加入的节点为master了,但是从图中看的出来,并没有slot槽位信息,我们还需要重新分槽,才能使用。

# ip端口是集群中任意一个节点和对应端口号
./redis-cli --cluster reshard  ip:port -a 密码 

-w653
询问需要迁移多少个slots,迁移之后,原来的数据还是存在与slots中的,因为哈希后取模的接口还是对应某个slot,数据还在。

填入需要迁移的节点id,也就是新增的master的id,复制进去。
-w1097

随后输入all,表示从每个现有master中都取出一定的slot进行迁移。(done的话是从指定的节点中拿出一部分slot来迁移)
然后再yes,表示执行reshard操作。
-w747
等待一段时间迁移后,迁移成功。重新检查集群信息。这个时候227中有2000个slot,分别都是从其他节点迁移的一部分共同组合的。
-w918
如此一来,新的master节点加入到集群了。

之前的name是在别的master中,由于slot迁移了,这个时候再查询的时候,他会路由到227节点,说明了数据不会因为节点增加而丢失,都会跟着slot走。
-w715

测试关闭这台新的master,由于slot不完整,集群不可用。其实也就是说明了整个集群形态下,总数16384个哈希槽必须都存在,缺少了就不完整了。所以就必定需要使用高可用,每个master下都要挂在至少1个slave。
-w472

新加slave,把他安排到某个特定的master之下

执行如下命令:

./redis-cli --cluster add-node --cluster-slave --cluster-master-id [master-id] [slave-ip:port] [master-ip:port] 

-w1851
添加节点成功。
这个时候查看,可以看到228加入到集群,并且成为了slave:
-w859
228的分片信息slave归属为227,如此一来slave添加到某个master下成功了。
-w635

Redis集群总结

  1. 读写都是在master,slave加入集群,会进行数据同步,连接集群中的任意主或从节点去读写数据,都会根据key哈希取模后路由到某个master节点去处理。slave不提供读写服务,只会同步数据。
  2. 关闭任意一主,会导致部分写操作失败,是由于从节点不能执行写操作,在Slave升级为Master期间会有少量的失败。
  3. 关闭从节点对于整个集群没有影响
  4. 某个主节点和他麾下的所有从节点全部挂掉,我们集群就进入faill状态,不可用。因为slot不完整。
  5. 如果集群超过半数以上master挂掉,无论他们是否有对应slave,集群进入fail状态,因为无法选举。
  6. 如果集群中的任意master宕机,且此master没有slave。集群不可用。(同3)
  7. 投票选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超时(cluster-node-timeout),认为当前master节点挂掉。
  8. 选举只会针对某个master下的所有slave选举,而不是对所有全量的slave选举。
  9. 原先的master重新恢复连接后,他会成为新master的从服务器。由于主从同步,客户端的写入命令,有可能会丢失(为啥?参考主从复制原理AOF与RDB)。redis并非强一致性,由于主从特性,所以最后一部分数据会丢失。CAP理论。
  10. 集群只实现了主节点的故障转移;从节点故障时只会被下线,不会进行故障转移。因此,使用集群时,一般不会使用读写分离技术,因为从节点故障会导致读服务不可用,可用性变差了。所以不要在集群里做读写分离。

公众号底部二维码
公众号底部知识星球二维码


风间影月
1 声望3 粉丝

互联网后端开发工程师,技术经理,项目经理,架构师,目前主要以分布式系统,集群,高可用负载均衡为主要方向。尚自习(www.itzixi.com)站长。