Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)

2022年05月13日 阅读数:3
这篇文章主要向大家介绍Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。
Redis Cluster集群原理+实战+故障切换

文章目录

1.redis cluster原理概念

1.1.cluster架构概念

redis cluster是redis的分布式解决方案,在3.0版本正式推出,若是公司的redis是2.x版本,就须要升级了node

redis哨兵集群不足之处:redis

  • 资源利用率低,只有一台主库对外提供服务
    • 假如哨兵模式有3个节点,只有其中一个节点对外提供服务,其余两个节点都处于备份状态,这样就会形成资源的浪费,redis将数据都写在内存中,只有主节点工做,那么内存只有主节点上的那点内存,从节点上的内存也就形成了浪费
  • 主库压力比较大,性能有瓶颈
    • 只有主库在工做,全部的写都是主节点完成,这样就会形成主节点的压力比较大,从节点几乎没有压力
  • 哨兵的不足之处就在于集群不是分布式存储,只是单节点去处理,若是集群时分布式存储,那么单点和压力的问题也就解决了

redis cluster适用场景:算法

  • 当redis遇到单机、内存、并发、流量等瓶颈时,能够采用cluster架构方案达到负载均衡的目的

redis cluster以前的分布式方案:shell

  • 客户端分区方案,优势分区逻辑可控,缺点是须要本身处理数据路由,高可用和故障转移等。
  • 代理方案,优势是简化客户端分布式逻辑和升级维护便利,缺点加剧架构部署和性能消耗。

redis cluster的数据分布方式: 全部分布式数据库首先要解决把整个数据库集安装分区规则映射到多个节点的问题,也就是把数据集划分到多个节点上,redis cluster采用哈希分片规则,这样就能保证每一个节点存储的数据量大体相同数据库

redis cluster原理:vim

redis cluster会将数据自动进行分片,而后经过hash算法均匀的存放在集群中的每一个节点,cluster架构在每台机器上都有一个或多个主节点和从节点,当一个节点上的master挂掉,会自动将这台机器上的某个slave切换为master服务器

cluster架构的redis集群,能够横向扩容,因为cluster是分布式架构,单个机器的内存是32G,那么10个节点就是320G内存的存储架构

cluster架构数据分片是由hash来进行分配的,均匀的分散在各个节点并发

cluster架构槽位概念:每一个cluster集群都有16384个槽位,这个槽位就是用来存储hash分配的分片,每个槽位都须要分配到位,有一个槽位没有分配,整个集群都将没法使用,每个槽位都有一个序号,它们不是顺序存放的,而是在节点一上好比有10-20序列槽位,节点二上有60-70序列的槽位,这两个节点都是10个槽位,序号不必定要顺序,可是数量必定要差很少,容许2%的偏差负载均衡

cluster集群架构图

经过hash分配数据分片到不一样的redis主机
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_数据

在应用端配置redis cluster地址时须要将全部节点的ip和端口都添加上

使用cluster集群建立的key,在哪一个节点上建立的只能是自身节点能够查到数据,其余节点看不到

1.2.redis cluster不合理的架构图

不太合理的架构图

cluster集群每一个机器上都有多个master和slave,若是master节点的数据备份都在本身主机的slave上,那么当服务器1坏掉后,这个机器上的数据就丢失了,数据丢失整个应用就崩溃了
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_数据库_02

合理的架构图

每一个节点slave都存放在别的主机,即便当前主机挂掉,另外一台直接还原数据便可

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_数据库_03

1.3.部署一个cluster三主三从集群具体步骤

1.在三台主机上部署redis,分别启动两个不一样端口的redis,一个主库一个从库

2.配置cluster集群自动发现,使得集群中各个主机都知道其余主机上的redis节点

3.配置集群hash分配槽位,有了槽位才能够存储数据

4.使用cluster replicate使多出来的三个主库变成从库,这样就实现了三主三从

1.4.环境准备

IP 主机名 端口号 节点
192.168.81.210 redis-1 6380 master
192.168.81.210 redis-1 6381 slave—>redis-2
192.168.81.220 redis-2 6380 master
192.168.81.220 redis-2 6381 slave—>redis-3
192.168.81.230 redis-3 6380 master
192.168.81.230 redis-3 6381 slave—>redis-1

2.部署redis cluster节点

搭建一个三主三从的redis cluster集群

配置文件中的bind也能够写成以下样子,自动识别bind地址

bind $(ifconfig | awk 'NR==2{print $2}')

配置文件含义

port 6380  					//redis端口
daemonize yes					//后台启动
logfile /data/redis_cluster/redis_6380/logs/redis_6380.log			//日志路径
pidfile /data/redis_cluster/redis_6380/pid/redis_6380.log		//pid存放路径
dbfilename "redis_6380.rdb"								//数据文件名称
dir /data/redis_cluster/redis_6380/data					//数据文件存放目录
cluster-enabled yes									//开启集群模式
cluster-config-file node_6380.conf					//集群数据文件路径,保存集群信息的文件
cluster-node-timeout 15000						//集群故障转移时间,多长时间无响应就切换

环境准备

IP 角色 端口
192.168.81.210 master 6380
192.168.81.210 slave 6381
192.168.81.220 master 6380
192.168.81.220 slave 6381
192.168.81.230 master 6380
192.168.81.230 slave 6381

2.1.redis-1配置

配置文件自动识别bind地址

1.建立节点配置文件路径
[root@redis-1 ~]# mkdir -p /data/redis_cluster/redis_{6380,6381}/{conf,data,logs,pid}

2.准备两个配置文件一个6380,一个6381
[root@redis-1 ~]# cat > /data/redis_cluster/redis_6380/conf/redis_6380.conf <<EOF
bind $(ifconfig | awk 'NR==2{print $2}')
port 6380  
daemonize yes
logfile /data/redis_cluster/redis_6380/logs/redis_6380.log
pidfile /data/redis_cluster/redis_6380/pid/redis_6380.log
dbfilename "redis_6380.rdb"
dir /data/redis_cluster/redis_6380/data
cluster-enabled yes
cluster-config-file node_6380.conf
cluster-node-timeout 15000
EOF
[root@redis-1 ~]# cat > /data/redis_cluster/redis_6381/conf/redis_6381.conf <<EOF
bind $(ifconfig | awk 'NR==2{print $2}')
port 6381  
daemonize yes
logfile /data/redis_cluster/redis_6381/logs/redis_6381.log
pidfile /data/redis_cluster/redis_6381/pid/redis_6381.log
dbfilename "redis_6381.rdb"
dir /data/redis_cluster/redis_6381/data
cluster-enabled yes
cluster-config-file node_6381.conf
cluster-node-timeout 15000
EOF

3.启动rediscluster
[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6380/conf/redis_6380.conf
[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6381/conf/redis_6381.conf

4.查看进程和端口
[root@redis-1 ~]# ps aux | grep redis
[root@redis-1 ~]# netstat -lnpt | grep redis

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_数据_04

2.2.redis-2配置

配置文件自动识别bind地址

[root@redis-2 ~]# mkdir -p /data/redis_cluster/redis_{6380,6381}/{conf,data,logs,pid}
[root@redis-2 ~]# cat > /data/redis_cluster/redis_6380/conf/redis_6380.conf <<EOF
bind $(ifconfig | awk 'NR==2{print $2}')
port 6380  
daemonize yes
logfile /data/redis_cluster/redis_6380/logs/redis_6380.log
pidfile /data/redis_cluster/redis_6380/pid/redis_6380.log
dbfilename "redis_6380.rdb"
dir /data/redis_cluster/redis_6380/data
cluster-enabled yes
cluster-config-file node_6380.conf
cluster-node-timeout 15000
EOF
[root@redis-2 ~]# cat > /data/redis_cluster/redis_6381/conf/redis_6381.conf <<EOF
bind $(ifconfig | awk 'NR==2{print $2}')
port 6381  
daemonize yes
logfile /data/redis_cluster/redis_6381/logs/redis_6381.log
pidfile /data/redis_cluster/redis_6381/pid/redis_6381.log
dbfilename "redis_6381.rdb"
dir /data/redis_cluster/redis_6381/data
cluster-enabled yes
cluster-config-file node_6381.conf
cluster-node-timeout 15000
EOF
[root@redis-2 ~]# 
[root@redis-2 ~]# redis-server /data/redis_cluster/redis_6380/conf/redis_6380.conf
[root@redis-2 ~]# redis-server /data/redis_cluster/redis_6381/conf/redis_6381.conf
[root@redis-2 ~]# 
[root@redis-2 ~]# ps aux | grep redis
[root@redis-2 ~]# netstat -lnpt | grep redis

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_配置文件_05

2.3.redis-3配置

手动填写bind ip地址

[root@redis-3 ~]# mkdir -p /data/redis_cluster/redis_{6380,6381}/{conf,data,logs,pid}
[root@redis-3 ~]# cat > /data/redis_cluster/redis_6380/conf/redis_6380.conf <<EOF
bind 192.168.81.230
port 6380  
daemonize yes
logfile /data/redis_cluster/redis_6380/logs/redis_6380.log
pidfile /data/redis_cluster/redis_6380/pid/redis_6380.log
dbfilename "redis_6380.rdb"
dir /data/redis_cluster/redis_6380/data
cluster-enabled yes
cluster-config-file node_6380.conf
cluster-node-timeout 15000
EOF
[root@redis-3 ~]# cat > /data/redis_cluster/redis_6381/conf/redis_6381.conf <<EOF
bind 192.168.81.230
port 6381  
daemonize yes
logfile /data/redis_cluster/redis_6381/logs/redis_6381.log
pidfile /data/redis_cluster/redis_6381/pid/redis_6381.log
dbfilename "redis_6381.rdb"
dir /data/redis_cluster/redis_6381/data
cluster-enabled yes
cluster-config-file node_6381.conf
cluster-node-timeout 15000
EOF
[root@redis-3 ~]# 
[root@redis-3 ~]# redis-server /data/redis_cluster/redis_6380/conf/redis_6380.conf
[root@redis-3 ~]# redis-server /data/redis_cluster/redis_6381/conf/redis_6381.conf
[root@redis-3 ~]# 
[root@redis-3 ~]# ps aux | grep redis
[root@redis-3 ~]# netstat -lnpt | grep redis

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_分布式_06

2.4.查看redis cluster进程

每一个节点启动了cluster后,进程名上会增长cluster

每一个redis节点会开放两个端口,服务端口6380,集群通讯端口16380(在服务端口基础上增长10000)

4.查看进程
[root@redis-1 ~]# ps aux | grep redis
avahi      6935  0.0  0.1  62272  2296 ?        Ss   1月29   0:02 avahi-daemon: running [redis-1.local]
root      31846  0.3  0.5 141068 10800 ?        Ssl  1月30  10:13 redis-server 192.168.81.210:6379
root      31859  0.3  0.4 136972  7744 ?        Ssl  1月30  11:43 redis-sentinel 192.168.81.210:26379 [sentinel]
root      78126  0.2  0.4 136972  7584 ?        Ssl  14:40   0:00 redis-server 192.168.81.210:6380 [cluster]
root      78130  0.4  0.4 136972  7588 ?        Ssl  14:40   0:00 redis-server 192.168.81.210:6381 [cluster]
root      78136  0.0  0.0 112728   988 pts/2    R+   14:40   0:00 grep --color=auto redis
[root@redis-1 ~]# netstat -lnpt | grep redis
tcp        0      0 192.168.81.210:26379    0.0.0.0:*               LISTEN      31859/redis-sentine 
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      31846/redis-server  
tcp        0      0 192.168.81.210:6379     0.0.0.0:*               LISTEN      31846/redis-server  
tcp        0      0 192.168.81.210:6380     0.0.0.0:*               LISTEN      78126/redis-server  
tcp        0      0 192.168.81.210:6381     0.0.0.0:*               LISTEN      78130/redis-server  
tcp        0      0 192.168.81.210:16380    0.0.0.0:*               LISTEN      78126/redis-server  
tcp        0      0 192.168.81.210:16381    0.0.0.0:*               LISTEN      78130/redis-server

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_redis_07

2.5.查看集群信息文件内容

集群模式的redis除了原有的配置文件以外又增长了一个集群配置文件,当集群内节点信息发生变化时,如添加节点,节点下线,故障转移等,节点都会自动保存集群状态到配置文件,redis自动维护集群配置文件,不须要手动修改防止节点重启时产生错乱

在集群启动后会生成一个数据文件,这个数据文件其实保存的就是集群的信息,在没有配置集群互相发现时,单个节点只保存本身的集群信息,文件中有节点id信息,每一个节点的id都是惟一的

当配置了互相发现了配置文件中就会增长全部节点的信息

[root@redis-1 ~]# cat /data/redis_cluster/redis_6380/data/node_6380.conf 
b7748aedb5e51921db67c54e0c6263ed28043948 :0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0

[root@redis-1 ~]# cat /data/redis_cluster/redis_6381/data/node_6381.conf 
1ec79d498ecf9f272373740e402398e4c69cacb2 :0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0

也能够登陆redis进行查看

[root@redis-1 ~]# for i in {1..3}
do
for j in {0..1}
do
echo "192.168.81.2${i}0---638${j}"
redis-cli -h 192.168.81.2${i}0 -p 638${j} cluster nodes
done
done
192.168.81.210---6380
b7748aedb5e51921db67c54e0c6263ed28043948 :6380 myself,master - 0 0 0 connected
192.168.81.210---6381
1ec79d498ecf9f272373740e402398e4c69cacb2 :6381 myself,master - 0 0 0 connected
192.168.81.220---6380
87ea6206f3db1dbaa49522bed15aed6f3bf16e22 :6380 myself,master - 0 0 0 connected
192.168.81.220---6381
bedd9482b08a06b0678fba01bb1c24165e56636c :6381 myself,master - 0 0 0 connected
192.168.81.230---6380
759ad5659d449dc97066480e1b7efbc10b34461d :6380 myself,master - 0 0 0 connected
192.168.81.230---6381
a2c95db5d6f9f288e6768c8d00e90fb7631f3021 :6381 myself,master - 0 0 0 connected

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_redis_08

3.配置cluster集群互相发现

3.1.互相发现概念

cluster集群互相发现只须要在一个节点上配置,全部节点都会接收到配置信息并自动加入到配置文件中

例如在redis-1的6380节点上增长了本机的6381端口和redis-2的6380端口,这时在redis-2上查看6380的配置里面就能看到6380节点和redis-1的6380以及6381节点信息,这时redis-3的两个节点还有本机的6381则仍是一条,由于他们没有加入

在哪一个节点添加的发现另外一个节点的信息,那么当前这个节点就已经加入到了集群中

其实只要在集群的任意一个节点配置,集群的全部节点都会自动添加配置

下面演示一个在reids-1上添加几个节点,在redis-2上看是否自动配置

1.在redis-1的6380节点上增长本机的6381和redis-2的6380端口
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6380
192.168.81.210:6380> CLUSTER MEET 192.168.81.210 6381
OK
192.168.81.210:6380> CLUSTER MEET 192.168.81.220 6380
OK

2.查看redis-2的6380集群配置文件
[root@redis-2 ~]# cat /data/redis_cluster/redis_6380/data/node_6380.conf 
1ec79d498ecf9f272373740e402398e4c69cacb2 192.168.81.210:6381 master - 0 1612169525469 1 connected
b7748aedb5e51921db67c54e0c6263ed28043948 192.168.81.210:6380 master - 0 1612169525369 0 connected
87ea6206f3db1dbaa49522bed15aed6f3bf16e22 192.168.81.220:6380 myself,master - 0 0 2 connected
vars currentEpoch 2 lastVoteEpoch 0
很明显的看出已经将redis-1的6380和6381以及redis-2本机的6380端口都加到了集群配置文件中

3.查看redis-2的6381节点集群配置文件
[root@redis-2 ~]# cat /data/redis_cluster/redis_6381/data/node_6381.conf 
bedd9482b08a06b0678fba01bb1c24165e56636c :0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0

3.2.将集群的全部节点进行互相发现

在集群的任意一个节点配置就能够

1.配置互相发现
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6380
192.168.81.210:6380> CLUSTER MEET 192.168.81.210 6381
OK
192.168.81.210:6380> CLUSTER MEET 192.168.81.220 6380
OK
192.168.81.210:6380> CLUSTER MEET 192.168.81.220 6381
OK
192.168.81.210:6380> CLUSTER MEET 192.168.81.230 6380
OK
192.168.81.210:6380> CLUSTER MEET 192.168.81.230 6381
OK

2.查看配置文件是否增长,全部节点的配置文件都会生成
[root@redis-1 ~]# cat /data/redis_cluster/redis_6381/data/node_6381.conf 
759ad5659d449dc97066480e1b7efbc10b34461d 192.168.81.230:6380 master - 0 1612169812886 4 connected
1ec79d498ecf9f272373740e402398e4c69cacb2 192.168.81.210:6381 myself,master - 0 0 1 connected
87ea6206f3db1dbaa49522bed15aed6f3bf16e22 192.168.81.220:6380 master - 0 1612169814797 2 connected
bedd9482b08a06b0678fba01bb1c24165e56636c 192.168.81.220:6381 master - 0 1612169815806 0 connected
a2c95db5d6f9f288e6768c8d00e90fb7631f3021 192.168.81.230:6381 master - 0 1612169815708 5 connected
b7748aedb5e51921db67c54e0c6263ed28043948 192.168.81.210:6380 master - 0 1612169816814 3 connected
vars currentEpoch 5 lastVoteEpoch 0

4.cluster集群分配操做

4.1.redis cluster通信流程

集群内消息传递是同步的

在分布式存储中须要提供维护节点元数据信息的机制,所谓元数据是指:节点负责哪些数据,是否出现故障灯状态信息,redis集群采用gossip协议,gossip协议工做原理就是节点彼此不断交换信息,一段时间后全部的节点偶会指定集群完整信息,这种方式相似于流言传播,所以只须要在一台节点配置集群信息全部节点都能收到信息

通讯过程:

​ 1.集群中的每个节点都会单独开辟一个tcp通道用于节点之间彼此通讯,通讯端口在基础端口上增长10000

​ 2.每一个节点在固定周期内经过特定规则选择结构节点发送ping消息

​ 3.接收到ping消息的节点用pong做为消息响应,集群中每一个节点经过必定规则挑选要通讯的节点,每一个节点可能知道所有节点的信息,也可能知道部分节点信息,只要这些节点彼此能够正常通讯,最终他们就会达成一致的状态,当节点出现故障,新节点加入,主从角色变化等,彼此之间不断发生ping/pong消息,最终达成同步的模板

通信消息类型:gossip,信息交换,常见的消息分为ping、pong、meet、fail

通信示意图
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_配置文件_09

没有分配槽位时集群的状态,全部节点执行cluster info,cluster_state都是fail,fail状态表示集群不可用,没有分配槽位,cluster_slots都会显示0

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_redis_10

4.2.手动配置集群槽位

每一个cluster集群都有16384个槽位,咱们有三台机器,想要手动分配平均就须要使用16384除3

redis-1 0-5461

redis-2 5642-10922

redis-3 10923-16383

分配槽位语法格式(交互式):CLUSTER ADDSLOTS 0 5461

分配槽位语法:redis-cli -h 192.168.81.210 -p 6380 cluster addslots {0…5461}

删除槽位分配语法格式: redis-cli -h 192.168.81.210 -p 6380 cluster delslots {5463…10921}

1.配置手动分配槽位
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6380 cluster addslots {0..5461}
OK
[root@redis-1 ~]# redis-cli -h 192.168.81.220 -p 6380 cluster addslots {5462..10922}
OK
[root@redis-1 ~]# redis-cli -h 192.168.81.230 -p 6380 cluster addslots {10923..16383}
OK

2.查看集群状态,到目前为止集群已是可用的了
[root@redis-1 ~]# redis-cli -h 192.168.81.220 -p 6380 cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:2
cluster_stats_messages_sent:170143
cluster_stats_messages_received:170142

3.查看nodes文件内容
[root@redis-1 ~]# redis-cli -h 192.168.81.220 -p 6380 cluster nodes
a2c95db5d6f9f288e6768c8d00e90fb7631f3021 192.168.81.230:6381 master - 0 1612251539412 5 connected
bedd9482b08a06b0678fba01bb1c24165e56636c 192.168.81.220:6381 master - 0 1612251538402 0 connected
87ea6206f3db1dbaa49522bed15aed6f3bf16e22 192.168.81.220:6380 myself,master - 0 0 2 connected 5462-10922
b7748aedb5e51921db67c54e0c6263ed28043948 192.168.81.210:6380 master - 0 1612251540418 3 connected 0-5461
1ec79d498ecf9f272373740e402398e4c69cacb2 192.168.81.210:6381 master - 0 1612251537394 1 connected
759ad5659d449dc97066480e1b7efbc10b34461d 192.168.81.230:6380 master - 0 1612251536386 4 connected 10923-16383

4.3.建立key验证集群是否可用

不是全部的key都能插入,有的key插入的时候就提示说你应该去192.168.81.230上插入,这时手动到对应的主机上执行就能够插入,这是因为cluster集群槽位都是分布在不一样节点的,每次新建一个key,都会经过hash算法均匀的在不一样节点去建立

不一样节点建立的key只由本身节点能够看到本身建立的数据

[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6380
192.168.81.210:6380> set k1 v1
(error) MOVED 12706 192.168.81.230:6380
192.168.81.210:6380> set k2 v2
OK
192.168.81.210:6380> set k3 v3
OK
192.168.81.210:6380> set k4 v4
(error) MOVED 8455 192.168.81.220:6380
192.168.81.210:6380> set k5 v5
(error) MOVED 12582 192.168.81.230:6380
192.168.81.210:6380> set k6 v6
OK

[root@redis-1 ~]# redis-cli -h 192.168.81.230 -p 6380
192.168.81.230:6380> set k1 v1
OK
192.168.81.230:6380> set k5 v5
OK

[root@redis-1 ~]# redis-cli -h 192.168.81.220 -p 6380
192.168.81.220:6380> set k4 v4
OK

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_redis_11

4.4.ASK路由解决key建立提示去别的主机建立

能够经过ASK路由解决建立key时提示去别的主机进行建立

ASK路由建立key时,若是能够在本机直接建立就会执行建立key的命令,若是不能再本机执行,他会根据提示的主机去对应主机上建立key

ASK路径的特性:每次经过hash在指定主机上建立了key后就会停留在这个主机上

只须要执行redis-cli时加上-c参数便可

[root@redis-1 ~]# redis-cli -c -h 192.168.81.210 -p 6380
192.168.81.210:6380> set k8 v8
-> Redirected to slot [8331] located at 192.168.81.220:6380
OK
192.168.81.220:6380> set k9 v9
-> Redirected to slot [12458] located at 192.168.81.230:6380
OK
192.168.81.230:6380> set k10 v10
OK
192.168.81.230:6380> set k11 v11
OK
192.168.81.230:6380> set k12 v12
-> Redirected to slot [2863] located at 192.168.81.210:6380
OK
192.168.81.210:6380> set k13 v13
-> Redirected to slot [6926] located at 192.168.81.220:6380
OK
192.168.81.220:6380> set k14 v14
-> Redirected to slot [11241] located at 192.168.81.230:6380
OK

很清楚的展现了在哪台主机上建立

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_数据库_12

4.5.验证hash分配是否均已

cluster架构是分布式的,建立的key会经过hash将数据均已的分布在每台主机的槽位上

1.插入一千条数据,查看三个节点是否分配均已
插入的时候使用-c,自动在某个节点上插入数据
[root@redis-1 ~]# for i in {1..1000}
do
redis-cli -c -h 192.168.81.210 -p 6380 set key_${i} value_${i}
done

2.查看每一个节点的数据量,能够看到很是均匀,偏差只有一点点
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6380
192.168.81.210:6380> DBSIZE
(integer) 339

[root@redis-1 ~]# redis-cli -h 192.168.81.220 -p 6380
192.168.81.220:6380> DBSIZE
(integer) 339

[root@redis-1 ~]# redis-cli -h 192.168.81.230 -p 6380
192.168.81.230:6380> DBSIZE
(integer) 336
192.168.81.230:6380> exit

5.配置cluster集群三主三从高可用

实现步骤:

​ 1.使用cluster replicate将主机的6381redis节点交叉成为别的主机6380节点的从库

​ 2.查看集群状态便可

5.1.三主三从架构图

三主三从是redis cluster最经常使用的架构,每一个从节点复制的都不是本机主库的数据,而是其余节点主库的数据,这样即便某一台主机坏掉了,从节点备份仍是在其余机器上,这样就作到了高可用,三主三从架构容许最多坏一台主机

三主三从咱们采用交叉复制架构类型,这样能够作到最多坏一台主机集群仍是正常能够用的,若是每台主机的6381节点都是6380节点的备份,那么这台机器坏了,集群就不可用了,所以想要作到高可用,就采用交叉复制

交叉复制的架构,当主节点挂掉了,主节点备份的从节点就会自动成为主节点,当主节点上线后

每一个节点的6380端口都是主库,6381端口都是从库

从节点对应的主节点关系:

​ redis-1的6381从节点对应的主节点是redis-2的6380主节点

​ redis-2的6381从节点对应的主节点是redis-3的6380主节点

​ redis-3的6381从节点对应的主节点是redis-1的6380主节点
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_数据库_13

5.2.将每个节点都配置rdb持久化

在全部节点端口的配置文件中加上rdb持久化配置便可

vim /data/redis_cluster/redis_6380/conf/redis_6380.conf 
bind 192.168.81.210
port 6380
daemonize yes
logfile /data/redis_cluster/redis_6380/logs/redis_6380.log
pidfile /data/redis_cluster/redis_6380/pid/redis_6380.log
dbfilename "redis_6380.rdb"
dir /data/redis_cluster/redis_6380/data
cluster-enabled yes
cluster-config-file node_6380.conf
cluster-node-timeout 15000
#持久化配置
save 60 10000
save 300 10
save 900 1

重启redis
redis-cli -h 192.168.81.210 -p 6380 shutdown
redis-server /data/redis_cluster/redis_6380/conf/redis_6380.conf

5.3.配置三主三从

配置三主三从规范操做步骤

1.将集群信息粘到txt中,只保留下6380端口信息

2.配置命令在txt中准备好在复制到命令行

主节点咱们已经有了,目前6个节点全是主节点,咱们须要把全部主机的6381的主节点配置成从节点

从节点对应的主节点关系:

​ redis-1的6381从节点对应的主节点是redis-2的6380主节点

​ redis-2的6381从节点对应的主节点是redis-3的6380主节点

​ redis-3的6381从节点对应的主节点是redis-1的6380主节点
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_配置文件_14

CLUSTER REPLICATE 是配置当前节点成为某个主节点的从节点,replicate命令其实就至关于执行了slaveof,同步了某一个主库,而且在日志中查看到的就是主从同步的过程

1.配置从节点链接主节点,交叉式复制
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6381 CLUSTER REPLICATE 87ea6206f3db1dbaa49522bed15aed6f3bf16e22
OK
[root@redis-1 ~]# redis-cli -h 192.168.81.220 -p 6381 CLUSTER REPLICATE 759ad5659d449dc97066480e1b7efbc10b34461d
OK
[root@redis-1 ~]# redis-cli -h 192.168.81.230 -p 6381 CLUSTER REPLICATE b7748aedb5e51921db67c54e0c6263ed28043948
OK

2.查看集群节点信息,发现已是三主三从了
[root@redis-1 ~]# redis-cli -h 192.168.81.230 -p 6381 cluster nodes
a2c95db5d6f9f288e6768c8d00e90fb7631f3021 192.168.81.230:6381 myself,slave b7748aedb5e51921db67c54e0c6263ed28043948 0 0 5 connected
bedd9482b08a06b0678fba01bb1c24165e56636c 192.168.81.220:6381 slave 759ad5659d449dc97066480e1b7efbc10b34461d 0 1612323918342 4 connected
b7748aedb5e51921db67c54e0c6263ed28043948 192.168.81.210:6380 master - 0 1612323919350 3 connected 0-5461
1ec79d498ecf9f272373740e402398e4c69cacb2 192.168.81.210:6381 slave 87ea6206f3db1dbaa49522bed15aed6f3bf16e22 0 1612323917331 2 connected
759ad5659d449dc97066480e1b7efbc10b34461d 192.168.81.230:6380 master - 0 1612323916826 4 connected 10923-16383
87ea6206f3db1dbaa49522bed15aed6f3bf16e22 192.168.81.220:6380 master - 0 1612323920357 2 connected 5462-10922

配置完主从,能够看到集群中已经有slave节点了,而且也是交叉复制的

打开主库的日志能够看到哪一个从库同步了主库的日志,打开从库的日志能够看到同步了哪一个主库的日志

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_redis_15

5.3.模拟故障转移

三主三从架构容许最多坏一台主机,模拟将redis-1机器的主库6380挂掉,查看集群间的故障迁移

思路:

​ 1.将redis-1的6380主库关掉,查看集群状态信息是否将slave自动切换为master

​ 2.当master上线后会变成一个节点的从库

​ 3.将master经过cluster failover从新成为主库

5.1.模拟坏掉redis-1的主库并验证就能是否可用

1.挂掉redis-1的主库
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6380 shutdown

2.查看日志
先是因为主库挂了状态变成fail,当从库变成主库后,状态再次变为ok
[root@redis-1 ~]# tail -f /data/redis_cluster/redis_6381/logs/redis_6381.log 
124058:S 03 Feb 13:16:00.233 # Cluster state changed: fail
124058:S 03 Feb 13:17:01.857 # Cluster state changed: ok

3.查看集群信息
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6381 cluster nodes

4.查看集群状态
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6381 cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:7
cluster_my_epoch:2
cluster_stats_messages_sent:18202
cluster_stats_messages_received:17036

5.验证集群是否可用
[root@redis-1 ~]# redis-cli -c -h 192.168.81.210 -p 6381 set k1111 v1111
OK

当主库挂掉后,查看集群信息时会看到提示主库已是fail状态,此时可用看到192.168.81.230机器的6381端口成为了master,192.168.81.230的6381端口是redis-1的从库,从库变为主库后,集群状态再次变为ok
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_配置文件_16

5.3.2.redis-1节点的主库恢复目前的架构图

当主库从新加入集群后,架构图就变成了以下样子,主库的6380就成为了192.168.81.230的从库,而192.168.81.230的从库变成了192.168.81.210的主库

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_配置文件_17

1.启动redis-1的6380主库
[root@redis-1 ~]# redis-server /data/redis_cluster/redis_6380/conf/redis_6380.conf 

2.查看集群信息
[root@redis-1 ~]# redis-cli -c -h 192.168.81.210 -p 6380 cluster nodes
1ec79d498ecf9f272373740e402398e4c69cacb2 192.168.81.210:6381 slave 87ea6206f3db1dbaa49522bed15aed6f3bf16e22 0 1612330250901 2 connected
b7748aedb5e51921db67c54e0c6263ed28043948 192.168.81.210:6380 myself,slave a2c95db5d6f9f288e6768c8d00e90fb7631f3021 0 0 3 connected
759ad5659d449dc97066480e1b7efbc10b34461d 192.168.81.230:6380 master - 0 1612330255958 4 connected 10923-16383
bedd9482b08a06b0678fba01bb1c24165e56636c 192.168.81.220:6381 slave 759ad5659d449dc97066480e1b7efbc10b34461d 0 1612330252920 4 connected
a2c95db5d6f9f288e6768c8d00e90fb7631f3021 192.168.81.230:6381 master - 0 1612330254941 7 connected 0-5461
87ea6206f3db1dbaa49522bed15aed6f3bf16e22 192.168.81.220:6380 master - 0 1612330256960 2 connected 5462-10922

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_数据库_18

5.3.3.将恢的主库从新变为主库

目前主库已经从新上线了,且如今是192.168.81.230的从库,而原来192.168.81.230的从库变成了如今192.168.81.210的主库,咱们须要把关系切换回来,不能让一台机器上同时存在两台主库,每次故障处理后必定要把架构修改会原来的样子

从库切换成主库也特别简单,只须要执行一个cluster falover便可变为主库

cluster falover确实也相似于关系互换,简单理解就是原来的从变成了主,如今的主变成了从,这样一来就能够把故障恢复的主机从新变为主库

cluster falover原理:falover原理也就是先执行了slave no one,而后在对应的由主库变为从库的机器上执行了slave of

1.将故障上线的主库从新成为主库
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6380 
192.168.81.210:6380> CLUSTER FAILOVER
OK

2.查看集群信息,192.168.81.210的发现6380从新成为了master,192.168.81.230的从库变成了slave
[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6381 cluster nodes
759ad5659d449dc97066480e1b7efbc10b34461d 192.168.81.230:6380 master - 0 1612331847795 12 connected 10923-16383
87ea6206f3db1dbaa49522bed15aed6f3bf16e22 192.168.81.220:6380 master - 0 1612331849307 11 connected 5462-10922
b7748aedb5e51921db67c54e0c6263ed28043948 192.168.81.210:6380 master - 0 1612331848299 10 connected 0-5461
bedd9482b08a06b0678fba01bb1c24165e56636c 192.168.81.220:6381 slave 759ad5659d449dc97066480e1b7efbc10b34461d 0 1612331850317 12 connected
a2c95db5d6f9f288e6768c8d00e90fb7631f3021 192.168.81.230:6381 slave b7748aedb5e51921db67c54e0c6263ed28043948 0 1612331851324 10 connected
1ec79d498ecf9f272373740e402398e4c69cacb2 192.168.81.210:6381 myself,slave 87ea6206f3db1dbaa49522bed15aed6f3bf16e22 0 0 8 connected

查看集群信息,192.168.81.210的发现6380从新成为了master,192.168.81.230的从库变成了slave

Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_数据_19

到此cluster集群故障转移成功,集群状态一切正常

[root@redis-1 ~]# redis-cli -h 192.168.81.210 -p 6380 cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:16
cluster_my_epoch:16
cluster_stats_messages_sent:18614
cluster_stats_messages_received:3497

6.redis cluster须要注意的几点

生产环境数据量可能很是大,当主库故障从新上线时,执行CLUSTER FAILOVER会很慢,由于这个就至关因而主从复制切换了,从库(刚上线的原来主库)关闭主从复制,主库(主库坏掉前的从库)同步从库(刚上线的原来主库)数据,而后从库(刚上线的原来主库)从新变为主库,这个时间必定要等,切记,千万不要由于慢在主库上(主库坏掉前的从库)同步手动进行了CLUSTER REPLICATE,这样确实会很是快的将主库(主库坏掉前的从库)从新变为从库,但也意味着这个节点数据所有丢失,由于clusert replicate至关于slaveof,slaveof会把本身的库清掉,这时候从库(刚上线的原来主库)在执行这CLUSTER FAILOVER同步着主库(主库坏掉前的从库)的数据,主库那边执行了replicate去同步从库(刚上线的原来主库),从而致使从库(刚上线的原来主库)尚未同步完主库(主库坏掉前的从库的数据),主库(主库坏掉前的从库)数据就丢失,整个集群仍是能够用的,只是这个主库节点和从节点数据所有丢失,其余两个主库从库还能使用。

切记,当从库执行CLUSTER FAILOVER变为主库时,必定不要在主库上执行CLUSTER REPLICATE变为从库,虽然CLUSTER REPLICATE变为从库很快,可是会清空本身的数据去同步主库,这时主库尚未数据,所以就会致使数据所有丢失

CLUSTER FAILOVER:首先执行slave on one变为一个单独的节点,而后在要变成从库的节点上执行slaveof,只要从库执行完slave of,执行CLUSTER FAILOVER的节点就变成了主库

CLUSTER REPLICATE:只是执行了slaveof使自身成为从节点

当redis cluster主从正在同步时,不要执行cluster replicate,当主从复制完在执行,如何看主从是否复制完就要看节点的rdb文件是不是.tmp结尾的,若是是tmp结尾就说明他们正在同步数据,此时不要对集群作切换操做

小总结:

​ 1.3.0版本之后推出集群功能

​ 2.cluster集群有16384个槽位,偏差在2%之间

​ 3.槽位与序号顺序无关,重点是槽的数量

​ 4.经过发现集群,与集群之间实现消息传递

​ 5.配置文件无需手动修改,都是自动生成的

​ 6.分配操做,必须将全部的槽位分配完毕

​ 7.理清复制关系,画图,按照图形执行复制命令

​ 8.当集群状态为ok时,集群才能够正常使用

​ 9.反复测试,批量插入key,验证分配是否均匀

​ 10.测试高可用,关闭任意主节点,集群是否自动转移

​ 11.当主节点修复后,执行主从关系切换

​ 12.作实验尽可能贴合生成环境,尽可能使用和生成环境同样数量的数据

​ 13.评估和记录同步数据、故障转移完成的时间

​ 14.向领导汇报时要有图、文档、实验环境,随时均可以演示

当应用须要链接redis cluster集群时要将全部节点都写在配置文件中
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)_分布式_20