Road to growth of rookie

Meaningful life is called life

0%

Reids 的三种集群模式搭建和入门

在开发中 Reids 是我们经常使用到的 NoSql 之一, 在生产环境中, 在某些特定的情况下 (例如: 给开发人员使用的只读库) 需要引入 Redis 的集群方案. Redis 支持三种集群方案: 主从复制模式Sentinel (哨兵) 模式Cluster 模式

image

准备三台虚拟机用于模拟 Redis 集群环境, 系统环境: Ubuntu Server 18.04

image

安装 Redis ServerRedis Cli

1
2
3
4
5
# https://timelate.com/archives/install-redis-on-ubuntu.html
sudo apt-get install software-properties-common -y
sudo add-apt-repository ppa:chris-lea/redis-server -y
sudo apt-get update && sudo apt-get install redis-server redis-tools -y
sudo redis-server -v

主从复制模式

主从复制模式下包含一台主数据库 (master) 和最少一台从数据库 slave. slave 启动后, 向 master 发送 SYNC 命令, master 接收到 SYNC 命令后通过 bgsave 保存快照 (RDB 持久化), 并使用缓冲区记录保存快照这段时间内执行的写命令; master 将保存的快找文件发送给 slave, 并继续执行执行的写明了; slave 接收到快照文件后, 加载快照文件并载入数据; master 在快照发送完成后开始向 slave 发送缓冲期的命令, slave 接收命令并执行, 完成复制初始化. 此后 master 每次执行一个写命令都会同步发送给 slave, 保持 masterslave 之间的数据一致性.

修改 master 的配置文件 sudo vim /etc/redis/redis.conf 并重启服务 sudo systemctl restart redis-server

1
2
bind 0.0.0.0 # 绑定监听的IP 0.0.0.0允许所有IP访问
requirepass 123456 # 密码

修改 slave 的配置文件 sudo vim /etc/redis/redis.conf 并重启服务 sudo systemctl restart redis-server

1
2
3
4
bind 0.0.0.0 # 绑定监听的IP 0.0.0.0允许所有IP访问
requirepass 123456 # 密码
replicaof 192.168.56.102 6379 # master 的 IP 和端口
masterauth 123456 # master 密码

masterslave 都配置后之后, 进入 master 写入一条数据, 立即访问 slave 查看, 或通过 info replication 命令也可以看到当前机器的主从状态

image

主从模式下 masterslave 之间的同步是以非阻塞的形式进行的, 同步期间, 客户端仍然可以提交查询和更新请求
主从模式不具备自动容错和恢复功能, masterslave 宕机都有可能导致客户端请求失败; 且难以支持在线扩容, Redis 的容量受限于单机配置

Sentinel (哨兵) 模式

哨兵模式基于主从复制模式, 只是引入了哨兵来监控与自动处理故障, 一旦发现问题能做出相应的应对处理, 其功能包括:

注意: 因为哨兵模式 基于主从模式, 所以开启哨兵模式之前, 需要 先开启主从模式

  • 监控 masterslave 是否正常运行
  • master 出现故障时, 能自动将一个 slave 转换为 master
  • 多个哨兵可以监控同一个 Redis, 哨兵之间也会自动监控

当哨兵与 master 建立连接后, 会定期 向 masterslave 发送 PING 命令 (1s一次); 如果被 PING 的数据库或节点超时未回复, 哨兵会认为其主观下线, 如果下线的是 master, 哨兵会向其他哨兵发送命令询问是否也认为该 master 主观下线, 当一定数量的哨兵都认为该 master 主管下线后, 哨兵会认为该 master 已经客观下线

当哨兵认为 master 客观下线时, 故障恢复的操作需要由选举的领头哨兵来执行, 选举通过 Raft 算法: 即发现 master 的哨兵节点向每个哨兵发送请求, 要求对方选自己为领头哨兵, 如果目标哨兵节点没有选过其他人, 则会同意当前请求; 如果超过一半的哨兵同意, 则发送请求的哨兵节点当选为领头哨兵; 如果多个哨兵节点同时参选, 可能存在一轮投票后无竞选者胜出, 此时每个参选的节点等待一个随机时间后再次发起参选请求, 直到选出领头哨兵

选举出 领头哨兵 后, 会从下线的 master 的从库中挑选出一个当做新的 master ; 挑出需要继任的 slave 后, 领头哨兵 向该数据库发送命令使其升格 为master, 然后再向其他 slave 发送命令接受新的 master, 最后更新数据. 将已经停止的旧的 master 更新为新的 master 的从库, 使其恢复服务后以 slave 的身份继续运行

为了模拟较为真实的生产环境, 多加两台虚拟机作为哨兵使用:

image

安装 redis-sentinel

1
$ sudo apt-get install redis-sentinel -y

修改两台 sentinel 机器配置: sudo vim /etc/redis/sentinel.conf

1
2
3
4
5
6
7
bind 0.0.0.0 # 绑定监听的IP 0.0.0.0允许所有IP访问
sentinel monitor mymaster 192.168.56.102 6379 1 # mymaster 定义一个 master 数据库的名称,后面是 master 的ip, port, 1 表示至少需要一个 Sentinel 进程同意才能将 master 判断为失效, 如果不满足这个条件, 则自动故障转移(failover)不会执行
sentinel auth-pass mymaster 123456 # master 的密码

sentinel down-after-milliseconds mymaster 5000 # 5s 未回复 PING, 则认为 master 主观下线,默认为 30s
sentinel parallel-syncs mymaster 2 # 指定在执行故障转移时, 最多可以有多少个 slave 实例在同步新的 master 实例, 在 slave 实例较多的情况下这个数字越小, 同步的时间越长, 完成故障转移所需的时间就越长
sentinel failover-timeout mymaster 300000 # 如果在该时间(ms)内未能完成故障转移操作, 则认为故障转移失败, 生产环境需要根据数据量设置该值

重启 redis-sentinel 服务之后, 可以通过 redis-cli -p 26379 连接到节点查看状态

image

master 执行以下命令关闭 redis-server 模拟 master 挂掉的场景, 然后进入 slave 中执行 info replication 查看两台 slave 的状态

1
$ sudo systemctl stop redis-server

image
image

杀死 master 后, 可以查看 slave 的状态可以看到, slave2 这台机器已经继任成了主库, 两台 sentinel 的对应的主库已经从 192.168.56.102 变成了 192.168.56.105

哨兵模式 基于主从模式, 但是相较于主从模式在 master 意外宕机后, 可以自动切换, 系统可用性更高
但是, 存在和组从模式存在一样的问题: 难以在线扩展、Redis 容量受单机限制; 并且, 需要额外的资源来启动 Sentinel 服务, 实现相对于复杂

Cluster 模式

哨兵模式解决了主从复制不能自动故障转移, 达不到高可用的问题, 但还是存在难以在线扩容, Redis 容量受限于单机配置的问题. Cluster 模式实现了 Redis 的 分布式存储, 即每台节点存储不同的内容, 来解决在线扩容的问题

Cluster 采用无中心结构, 所有的 Redis 节点彼此互联( PING 机制), 节点是否失效是通过集群中超过半数的节点检测失效时才生效. 客户端与 Redis 节点直连, 不需要中间代理层. 客户端不需要连接集群所有节点, 只需要连接集群中任何一个可用节点

Cluster 模式采用分布式存储, 在每个节点上, 都有一个插槽 (slot), 取值范围为 0-16383. 当存取 key 时, 节点会根据 CRC16 的算法得出一个结果, 然后把结果对 16384 求余, 求得的余被用来确定对应的数据存储在哪个节点中, 集群中的每个节点都存储了一份类似路由表的东西, 描述每个节点所拥有的 Slots; 当用户请求一个不在请求节点的 key 时, 它可以根据这个路由表找到正确的服务节点, 告知用户正确的服务节点

Cluster 模式集群节点最小配置 6 个节点(3 主 3 从, 因为需要半数以上), 其中主节点提供读写操作, 从节点作为备用节点, 不提供请求, 只作为故障转移使用。

修改所有机器的配置文件 sudo vim /etc/redis/redis.conf

1
2
3
4
5
6
bind 0.0.0.0 # 绑定监听的IP 0.0.0.0允许所有IP访问
requirepass 123456 # 密码
cluster-enabled yes # 开启集群模式
masterauth 123456 # 如果设置了密码,需要指定master密码
cluster-config-file nodes-xxx.conf # 集群的配置文件
cluster-node-timeout 15000 # 请求超时 默认15秒,可自行设置

修改完所有机器的配置文件后, 使用 redis-cli 启动集群

1
$ redis-cli --cluster create --cluster-replicas 1 192.168.56.102:6379 192.168.56.103:6379 192.168.56.105:6379 192.168.56.106:6379 192.168.56.107:6379 192.168.56.108:6379 -a 123456