Redis Cluster 搭建准备工作
- 搭建集群之前,务必有一点需要注意就是选举,因为在如今很多的分布式中间件里,集群都会有选举这个概念,一定要达到半数以上的节点,才能够发起公平的投票,否则就会脑裂,比如redis,zk,es等,所以至少保证3个master节点,master会发起选举投票的。这一点要须知。
配置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)
- 每个节点搭建单机redis,清理aof和rdb文件(预先做好)
- 如果为单实例的Redis设置了密码password,那么每个节点都必须要设置masterauth,也就是对应密码,这样是为了master挂掉以后,对应的slave可以升级为master。
- 需要注意,选举的过程会短暂的对外不可用。
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
从上图中可以看到,slots槽,用于装数据,主节点有,从节点没有。
在任意节点查看集群信息:
./redis-cli --cluster check 192.168.1.221:6379 -a 123456
查看主从状态信息:
./redis-cli -a 123456
info replication
搭建集群时的日志
M221与S225
M222与S226
M223与S224
从节点日志,主要进行复制:
cluster nodes
查看各个节点的信息
故障转移
如果一个master挂了,那么剩余的2个master会发起投票选举,从挂了的master对应的slave中选举出一个新的master,发生故障的master不会参与投票,这个要注意。
选举的时候需要半数以上的master都投票给同一个slave,那么他才会成为新的master。所以redis集群中至少需要3个主节点,2个是不行的。而且我们也是建议在不同的物理节点上去进行配置,如果是伪分布式集群,那么可能会有问题。
故障转移的主要流程首先是主观下线,然后是客观下线,这个我们在课程里有说过,要以客观为主,也就是半数以上的master都收不到某节点的心跳,则认为他宕机了,此时发起选举。
验证故障转移
- redis宕机,停止某一台master,观察日志,以及对应的从。
上图中,225升级为master,原来的221下线。slots自动重新分配。 - 重启原来的221,可以发现,他加入到了225的麾下,成为他的slave,并且进行了主从数据同步。
在新的主225中可以看到221的加入ask询问同步等信息 - 直接关闭225服务器,直接关停,相当于服务器炸了。测试后发现,221成为新的master,也就是说不论是redis宕机还是服务器炸了,对应的slave都能被选举为新的master,因为只要master集群客观认为你下线了,那么就会进行选举。
验证数据能否都在主从中获取
./redis-cli -a 123456 -c
set name lee
集群中设值与取值,需要加-c
。
图中数据进入到了主222中,那么验证一下从某个从节点中能不能获取,他会跳转到222中去获取,因为现在是一个集群形态。
如果不加-c
,以单实例形式去操作,那么会报错。
关闭主222,观察原来设置的数据,在slave226转变为master后,数据是否存在:
因为数据会主从同步,所以master宕机后,slave中还是会有他的数据。这些数据都是跟着slot走的。
master宕机,他的slave升级为master,再次宕机,看看剩余的2主2从能否运行
紧接上面的,接着关闭新主226,剩余2主2从,查看状态,你会发现出错,提示说slots分配不均匀,因为有一对主从没有的slot都没了。
随后在任意节点去查询数据,提示说当前集群不可用,我们需要恢复了。
多master宕机数超过半数以上,集群不可用
同时有2个redis-master都宕机,那么无法达到半数以上,此时无法选举,当前集群不可用。由于速度比较快,虚拟机里难以演示,所以此处意会一下哈~
(如果半数以上 Master 处于关闭状态那么整个集群处于不可用状态。)
集群节点通信 gossip了解即可,无需深究
redis集群模式下的几个节点之间也会相互通信,他们的通信协议是gossip,各个节点之间会有ping pong等消息类型,每个节点也维护着redis的元数据,一旦发生更改会相互发送。
redis 水平扩容,增加节点,重新shard分配slot
新增192.168.1.227
修改redis.conf文件后,启动服务。查看分片信息:
对比现有的master
对比后他自己虽然标识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
如上图,新节点,加入成功。
这个时候新加入的节点为master了,但是从图中看的出来,并没有slot槽位信息,我们还需要重新分槽,才能使用。
# ip端口是集群中任意一个节点和对应端口号
./redis-cli --cluster reshard ip:port -a 密码
询问需要迁移多少个slots,迁移之后,原来的数据还是存在与slots中的,因为哈希后取模的接口还是对应某个slot,数据还在。
填入需要迁移的节点id,也就是新增的master的id,复制进去。
随后输入all
,表示从每个现有master中都取出一定的slot进行迁移。(done
的话是从指定的节点中拿出一部分slot来迁移)
然后再yes
,表示执行reshard操作。
等待一段时间迁移后,迁移成功。重新检查集群信息。这个时候227中有2000个slot,分别都是从其他节点迁移的一部分共同组合的。
如此一来,新的master节点加入到集群了。
之前的name是在别的master中,由于slot迁移了,这个时候再查询的时候,他会路由到227节点,说明了数据不会因为节点增加而丢失,都会跟着slot走。
测试关闭这台新的master,由于slot不完整,集群不可用。其实也就是说明了整个集群形态下,总数16384个哈希槽必须都存在,缺少了就不完整了。所以就必定需要使用高可用,每个master下都要挂在至少1个slave。
新加slave,把他安排到某个特定的master之下
执行如下命令:
./redis-cli --cluster add-node --cluster-slave --cluster-master-id [master-id] [slave-ip:port] [master-ip:port]
添加节点成功。
这个时候查看,可以看到228加入到集群,并且成为了slave:
228的分片信息slave归属为227,如此一来slave添加到某个master下成功了。
Redis集群总结
- 读写都是在master,slave加入集群,会进行数据同步,连接集群中的任意主或从节点去读写数据,都会根据key哈希取模后路由到某个master节点去处理。slave不提供读写服务,只会同步数据。
- 关闭任意一主,会导致部分写操作失败,是由于从节点不能执行写操作,在Slave升级为Master期间会有少量的失败。
- 关闭从节点对于整个集群没有影响
- 某个主节点和他麾下的所有从节点全部挂掉,我们集群就进入faill状态,不可用。因为slot不完整。
- 如果集群超过半数以上master挂掉,无论他们是否有对应slave,集群进入fail状态,因为无法选举。
- 如果集群中的任意master宕机,且此master没有slave。集群不可用。(同3)
- 投票选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超时(cluster-node-timeout),认为当前master节点挂掉。
- 选举只会针对某个master下的所有slave选举,而不是对所有全量的slave选举。
- 原先的master重新恢复连接后,他会成为新master的从服务器。由于主从同步,客户端的写入命令,有可能会丢失(为啥?参考主从复制原理AOF与RDB)。redis并非强一致性,由于主从特性,所以最后一部分数据会丢失。CAP理论。
- 集群只实现了主节点的故障转移;从节点故障时只会被下线,不会进行故障转移。因此,使用集群时,一般不会使用读写分离技术,因为从节点故障会导致读服务不可用,可用性变差了。所以不要在集群里做读写分离。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。