Redis 集群
一、Redis集群简介

- Redis集群是一个提供在多个Redis节点间共享数据的程序集
- ,每个Master又可以挂载多个Slave
- 由于Cluster自带Sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能
- 客户端与Redis的节点连接,不再需要连接集群中所有的节点,只需要任意连接集群中的一个可用节点即可
- 负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系
- ,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽
- 使用Redis集群时我们会将存储的数据分散到多台redis机器上,这称为分片。简言之,集群中的每个Redis实例都被认为是整个数据的一个分片。
- 如何找到给定key的分片,为了找到给定key的分片,我们对kev进行CRC16(key)算法处理并通过对总分片数量取模。然后,使用确定性哈希函数,这意味着给定的key将多次始终映射到同一个分片,我们可以推断将来读取特定key的位置。
引入分片和槽位的优势:
这种结构很容易添加或者删除节点,比如如果我想新添加个节点D,我需要从节点 A, B,C中的部分槽转移到D上,如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可.由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。
3 哈希槽分区
Redis 集群中内置了 16384 个哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。当需要在 Redis 集群中放置一个key-value时,redis先对key使用crc16算法算出一个结果,然后用结果对16384求余数[CRC16(key)% 16384],这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,也就是映射到某个节点上。
二、搭建步骤
1 配置文件
新建6个配置文件,修改为不同的端口
mkdir -p /data/redis/cluster
cd /data/redis/cluster
touch cluster6379.conf cluster6380.conf cluster6381.conf cluster6382.conf cluster6383.conf cluster6384.conf
bind 0.0.0.0
daemonize yes
protected-mode no
port 6379
#port 6380
#port 6381
#port 6382
#port 6383
#port 6384
# 日志
logfile "/data/redis/cluster/cluster6379.log"
#logfile "/data/redis/cluster/cluster6380.log"
#logfile "/data/redis/cluster/cluster6381.log"
#logfile "/data/redis/cluster/cluster6382.log"
#logfile "/data/redis/cluster/cluster6383.log"
#logfile "/data/redis/cluster/cluster6384.log"
pidfile /data/redis/cluster/cluster6379.pid
#pidfile /data/redis/cluster/cluster6380.pid
#pidfile /data/redis/cluster/cluster6381.pid
#pidfile /data/redis/cluster/cluster6382.pid
#pidfile /data/redis/cluster/cluster6383.pid
#pidfile /data/redis/cluster/cluster6384.pid
dir /data/redis/cluster/
# rdb文件
dbfilename dump6379.rdb
#dbfilename dump6380.rdb
#dbfilename dump6381.rdb
#dbfilename dump6382.rdb
#dbfilename dump6383.rdb
#dbfilename dump6384.rdb
# 打开aof
appendonly yes
appendfilename "appendonly6379.aof"
#appendfilename "appendonly6380.aof"
#appendfilename "appendonly6381.aof"
#appendfilename "appendonly6382.aof"
#appendfilename "appendonly6383.aof"
#appendfilename "appendonly6384.aof"
requirepass 111111
# 访问主节点密码
masterauth 111111
# 打开集群配置
cluster-enabled yes
# 集群的配置文件(会自动生成)
cluster-config-file nodes-6379.conf
#cluster-config-file nodes-6380.conf
#cluster-config-file nodes-6381.conf
#cluster-config-file nodes-6382.conf
#cluster-config-file nodes-6383.conf
#cluster-config-file nodes-6384.conf
# 集群连接超时时间
cluster-node-timeout 5000
2 启动6个Redis实例
redis-server /data/redis/cluster/cluster6379.conf
redis-server /data/redis/cluster/cluster6380.conf
redis-server /data/redis/cluster/cluster6381.conf
redis-server /data/redis/cluster/cluster6382.conf
redis-server /data/redis/cluster/cluster6383.conf
redis-server /data/redis/cluster/cluster6384.conf

3 执行构建主从关系命令
# --cluster-replicas 1 表示为每个master创建一个salve节点
redis-cli -a 111111 --cluster create --cluster-replicas 1 192.168.163.126:6379 192.168.163.126:6380 192.168.163.126:6381 192.168.163.126:6382 192.168.163.126:6383 192.168.163.126:6384



检查集群情况
redis-cli -a 111111 --cluster check 192.168.163.126:6379

以下是本次分配的结果:
master | salve |
---|---|
192.168.163.126:6379@16379 | 192.168.163.130:6384@16384 |
192.168.163.130:6381@16381 | 192.168.163.130:6383@16383 |
192.168.163.130:6380@16380 | 192.168.163.130:6382@16382 |
4 集群的读写操作
客户端登陆时,需要加上-c
参数,才会把key路由到对应的槽位
redis-cli -p 6379 -a 111111 -c

加上-c
参数会根据key的槽位自动路由到其他节点
5 集群的容错切换
5.1 关闭6379节点

5.2 进入6380,查看集群状态,发现6384已晋升为主节点,6379为下线状态

5.3 重启6379,再次查看集群状态,发现6379变为从节点,主节点为6384

5.4 此时的集群状态

master | salve |
---|---|
192.168.163.130:6381@16381 | 192.168.163.130:6383@16383 |
192.168.163.130:6380@16380 | 192.168.163.130:6382@16382 |
5.5 集群主从关系调整命令
# 进入6379从节点
redis-cli -p 6379 -a 111111
# 执行cluster failover命令
cluster failover

master | salve |
---|---|
192.168.163.130:6381@16381 | 192.168.163.130:6383@16383 |
192.168.163.130:6380@16380 | 192.168.163.130:6382@16382 |
6 扩容
6.1 新增2个节点
新增两个配置文件cluster6385.conf,cluster6386.conf
bind 0.0.0.0
daemonize yes
protected-mode no
port 6385
#port 6386
# 日志
logfile "/data/redis/cluster/cluster6385.log"
#logfile "/data/redis/cluster/cluster6386.log"
pidfile /data/redis/cluster/cluster6385.pid
#pidfile /data/redis/cluster/cluster6386.pid
dir /data/redis/cluster/
# rdb文件
dbfilename dump6385.rdb
#dbfilename dump6386.rdb
# 打开aof
appendonly yes
appendfilename "appendonly6385.aof"
#appendfilename "appendonly6386.aof"
requirepass 111111
# 访问主节点密码
masterauth 111111
# 打开集群配置
cluster-enabled yes
# 集群的配置文件(会自动生成)
cluster-config-file nodes-6385.conf
#cluster-config-file nodes-6386.conf
# 集群连接超时时间
cluster-node-timeout 5000
启动6385、6386节点
redis-server /data/redis/cluster/cluster6385.conf
redis-server /data/redis/cluster/cluster6386.conf
6.2 加入集群命令
#将新增的6385作为master节点加入原有集群
#redis-cli -a 密码 --cluster add-node 192.168.163.126:6385 192.168.163.126:6379
#6385就是将要作为master新增节点 6379就是原来集群节点里面的领路人,相当于6385通过6379从而找到组织加入集群
redis-cli -a 111111 --cluster add-node 192.168.163.126:6385 192.168.163.126:6379

查看集群状态,发现新加入的master6385并没有分配槽位
redis-cli -a 111111 --cluster check 192.168.163.126:6379

6.3 重新分配槽号
# 命令:redis-cli -a 密码 --cluster reshard IP地址:端口号
redis-cli -a 111111 --cluster reshard 192.168.163.126:6385
- 分配中首先会让你输入分配多少个槽位,输入4096(16384 / 4 = 4096)
- 分配槽位的id,找到6385节点对应的id
- 输入all,选择所有节点重新分配

6.4 检查集群情况
redis-cli -a 111111 --cluster check 192.168.163.126:6379
四个主节点、一个节点4096个槽位

6.5 从节点挂载到新加入集群的主节点
#redis-cli -a 密码 --cluster add-node 新salve 新master --cluster-slave --cluster-master-id 新master的id
redis-cli -a 111111 --cluster add-node 192.168.163.126:6386 192.168.163.126:6385 --cluster-slave --cluster-master-id ad5dff8109241d3edeac55cf7a23b6c5f8f9a368

再次检查集群情况
redis-cli -a 111111 --cluster check 192.168.163.126:6379

此时集群状态
master | salve |
---|---|
192.168.163.126:6379@16379 | 192.168.163.130:6384@16384 |
192.168.163.130:6381@16381 | 192.168.163.130:6383@16383 |
192.168.163.130:6380@16380 | 192.168.163.130:6382@16382 |

7 缩容
7.1 清除从节点
# 命令:redis-cli -a 密码 --cluster del-node 从机ip:从机端口 从机id
redis-cli -a 111111 --cluster del-node 192.168.163.126:6386 2c381e20269340df899f6b340caa13aee94cf577
7.2 主节点归还槽号
redis-cli -a 111111 --cluster reshard 192.168.163.126:6385
依次输入**、、**、done、yes


7.3 清除主节点,恢复成3主3从
# 命令:redis-cli -a 密码 --cluster del-node 主机ip:主机端口 主机id
redis-cli -a 111111 --cluster del-node 192.168.163.126:6385 ad5dff8109241d3edeac55cf7a23b6c5f8f9a368
# 查看状态
redis-cli -a 111111 --cluster check 192.168.163.126:6379

三、集群配置
cluster-require-full-coverage
默认YES,现在集群架构是3主3从的redis cluster由3个master平分16384个slot,每个master的小集群负责1/3的slot,对应一部分数据。
cluster-require-full-coverage: 默认值 yes,即需要集群完整性,方可对外提供服务 通常情况,如果这3个小集群中,任何一个(1主1从)挂了,你这个集群对外可提供的数据只有2/3了, 整个集群是不完整的, redis 默认在这种情况下,是不会对外提供服务的。
如果你的诉求是,集群不完整的话也需要对外提供服务,需要将该参数设置为no ,这样的话你挂了的那个小集群是不行了,但是其他的小集群仍然可以对外提供服务。