复制是高可用 Redis
的基础,哨兵 和 集群 都是在 复制基础 上实现高可用的。复制主要实现了数据的多机备份以及对于读操作的负载均衡和简单的故障恢复。缺陷是故障恢复无法自动化、写操作无法负载均衡、存储能力受到单机的限制
一、Redis复制
1、复制简介
Redis 通过 slaveof host port
命令来让一个服务器成为另一个服务器的从服务器。
主要是通过masterserver持久化的rdb文件实现的。masterserver先dump出内存快照文件,然后将rdb文件传给slave server,slave server根据rdb文件重建内存表。
一个主服务器可以有多个从服务器。不仅主服务器可以有从服务器,从服务器也可以有自己的从服务器, 多个从服务器之间可以构成一个主从链。
一个从服务器只能有一个主服务器,并且不支持主主复制。
可以通过复制功能来让主服务器免于执行持久化操作: 只要关闭主服务器的持久化功能, 然后由从服务器去执行持久化操作即可。
在使用 Redis 复制功能时的设置中,强烈建议在 master 和在 slave 中启用持久化。当不启用时,例如由于非常慢的磁盘性能而导致的延迟问题,应该配置实例来避免重置后自动重启。
从 Redis 2.6 开始, 从服务器支持只读模式, 并且该模式为从服务器的默认模式。
- 只读模式由
redis.conf
文件中的slave-read-only
选项控制, 也可以通过 CONFIG SET parameter value 命令来开启或关闭这个模式。 - 只读从服务器会拒绝执行任何写命令, 所以不会出现因为操作失误而将数据不小心写入到了从服务器的情况。
2、复制原理
PSYNC
命令具有完整重同步和部分重同步两种模式:
完整重同步(full resychronization)
- 用于初次复制。执行步骤与SYNC
命令基本一致。部分重同步(partial resychronization)
- 用于断线后重复制。如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只需接收并执行这些写命令,即可将主从服务器的数据库状态保持一致。
1、部分重同步
部分重同步功能实现由三个部分构成:
- 主从服务器的复制偏移量(replication offset)
- 主服务器的复制积压缓冲区(replication backlog)
- 服务器的运行 ID
1、复制偏移量
主服务器和从服务器会分别维护一个复制偏移量。
- 如果主从服务器的复制偏移量相同,则说明二者的数据库状态一致;
- 反之,则说明二者的数据库状态不一致。
2、复制积压缓冲区
复制积压缓冲区是主服务器维护的一个固定长度的先进先出(FIFO)队列,默认大小为 1MB
。
复制积压缓冲区会保存一部分最近传播的写命令,并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量。
当从服务器断线重连主服务时,从服务器会通过 PSYNC
命令将自己的复制偏移量 offset 发送给主服务器,主服务器会根据这个复制偏移量来决定对从服务器执行何种同步操作。
- 如果 offset 之后的数据仍然在复制积压缓冲区,则主服务器对从服务器执行部分重同步操作。
- 反之,则主服务器对从服务器执行完整重同步操作。
🔔 注意:合理调整复制积压缓冲区的大小
Redis 复制积压缓冲区默认大小为
1MB
。复制积压缓冲区的最小大小可以根据公式
second * write_size_per_second
估算。
3、服务器的运行 ID
- 每个 Redis 服务器,都有运行 ID,用于唯一识别身份。
- 运行 ID 在服务器启动时自动生成,由 40 个随机的十六进制字符组成。例如:132e358005e29741f8d7b0a42d666aace286edda
从服务器对主服务器进行初次复制时,主服务器会将自己的运行 ID 传送给从服务器,从服务器会将这个运行 ID 保存下来。
当从服务器断线重连一个主服务器时,从服务器会发送之前保存的运行 ID:
- 如果保存的运行 ID 和当前主服务器的运行 ID 一致,则说明从服务器断线之前连接的就是这个主服务器,主服务器可以继续尝试执行部分重同步操作;
- 反之,若运行 ID 不一致,则说明从服务器断线之前连接的不是这个主服务器,主服务器将对从服务器执行完整重同步操作。
2、PSYNC 命令
了解了部分重同步的实现,PSYNC 的实现就很容易理解了,它的基本工作原理大致如下:
当从服务接收到 SLAVEOF
命令时,先判断从服务器以前是否执行过复制操作。
- 如果没有复制过任何主服务器,向要复制的主服务器发送
PSYNC ? -1
命令,主动请求进行完整重同步。 - 反之,向要复制的主服务器发送
PSYNC <runid> <offset>
命令。runid
是上一次复制的主服务器的运行 ID。offset
是复制偏移量。
接收到 PSYNC <runid> <offset>
命令的主服务会进行分析:
- 假如主从服务器的 master run id 相同,并且指定的偏移量(offset)在内存缓冲区中还有效,复制就会从上次中断的点开始继续。
- 如果其中一个条件不满足,就会进行完全重新同步(在 2.8 版本之前就是直接进行完全重新同步)。
3、心跳检测
在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令:
REPLCONF ACK <replication_offset>
其中,replication_offset
是从服务器当前的复制偏移量。
发送 REPLCONF ACK
命令对于主从服务器有三个作用:
- 检测主从服务器的网络连接状态。
- 辅助实现 min-slaves 选项。
- 检测命令丢失。
1、检测主从连接状态
可以通过发送和接收 REPLCONF ACK
命令来检查主从服务器之间的网络连接是否正常:如果主服务器超过一秒没有收到从服务器发来的 REPLCONF ACK
命令,那么主服务器就知道主从服务器之间的连接出现问题了。
可以通过向主服务器发送 INFO replication
命令,在列出的从服务器列表的 lag 一栏中,可以看到从服务器向主服务器发送 REPLCONF ACK
命令已经过去多少秒。
2、辅助实现 min-slaves 选项
Redis 的 min-slaves-to-write
和 min-slaves-max-lag
两个选项可以防止主服务器在不安全的情况下执行写命令。
【示例】min-slaves 配置项
min-slaves-to-write 3
min-slaves-max-lag 10
以上配置表示:从服务器小于 3 个,或三个从服务器的延迟(lag)都大于等于 10 秒时,主服务器将拒绝执行写命令。
3、检测命令丢失
如果因为网络故障,主服务传播给从服务器的写命令丢失,那么从服务器定时向主服务器发送 REPLCONF ACK
命令时,主服务器将发觉从服务器的复制偏移量少于自己的。然后,主服务器就会根据从服务器提交的复制偏移量,在复制积压缓冲区中找到从服务器缺少的数据,并将这些数据重新发送给从服务器。
4、复制的过程
1、slave server启动连接到master server之后,salve server主动发送SYNC命令给masterserver
2、masterserver接受SYNC命令之后,判断是否有正在进行内存快照的子进程,如果有,则等待其结束,否则,fork一个子进程,子进程把内存数据保存为文件,并发送给slave server。
3、masterserver子进程进程做数据快照时,父进程可以继续接收client端请求写数据,此时,父进程把新写入的数据放到待发送缓存队列中
4、slaveserver接收内存快照文件之后,清空内存数据,根据接收的快照文件,重建内存表数据结构
5、masterserver把快照文件发送完毕之后,发送缓存队列中保存的子进程快照期间改变的数据给slave server,slave server做相同处理,保存数据一致性
6、master server后续接收的数据,都会通过步骤1建立的连接,把数据发送到slave server
::: warning
slaveserver如果因为网络或其他原因断与masterserver的连接,当slaveserver重新连接时,需要重新获取masterserver的内存快照文件,slaveserver的数据会自动全部清空,然后再重新建立内存表,这样会让slaveserver启动恢复服务比较慢,同时也给masterserver带来较大压力,可以看出redis的复制没有增量复制的概念,这是redis主从复制的一个主要弊端,在实际环境中,尽量规避中途增加从库
:::
5、复制的流程
通过向从服务器发送如下 SLAVEOF 命令,可以让一个从服务器去复制一个主服务器。
SLAVEOF <master_ip> <master_port>
1、设置主从服务器
配置一个从服务器非常简单, 只要在从节点配置文件中增加以下的这一行就可以了:
slaveof 127.0.0.1 6379
当然, 你需要将代码中的 127.0.0.1
和 6379
替换成你的主服务器的 IP 和端口号。
另外一种方法是调用 SLAVEOF host port 命令, 输入主服务器的 IP 和端口, 然后同步就会开始:
127.0.0.1:6379> SLAVEOF 127.0.0.1 10086
OK
2、主从服务器建立 TCP 连接。
3、发送 PING 检查通信状态。
4、身份验证。
如果主服务器没有设置 requirepass
,从服务器没有设置 masterauth
,则不进行身份验证;反之,则需要进行身份验证。如果身份验证失败,则放弃执行复制工作。
如果主服务器通过 requirepass
选项设置了密码, 那么为了让从服务器的同步操作可以顺利进行, 我们也必须为从服务器进行相应的身份验证设置。
对于一个正在运行的服务器, 可以使用客户端输入以下命令:
config set masterauth <password>
要永久地设置这个密码, 那么可以将它加入到配置文件中:
masterauth <password>
另外还有几个选项, 它们和主服务器执行部分重同步时所使用的复制流缓冲区有关, 详细的信息可以参考 Redis 源码中附带的 redis.conf
示例文件。
5、发送端口信息。
从服务器执行 REPLCONF listening-port <port-number>
,向主服务器发送从服务器的监听端口号。
6、同步。
前文已介绍,此处不赘述。
7、命令传播。
在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务发送命令:
REPLCONF ACK <replication_coffset>
命令的作用:
- 检测主从服务器的网络连接状态。
- 辅助实现 min-slave 选项。
- 检测命令丢失。
8、解除主从
执行命令 SLAVEOF NO ONE 将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。
127.0.0.1:6379> slaveof no one
9、查看复制信息
主节点
127.0.0.1:6379> info replication
# Replication
# 角色
role:master
# 从节点的连接数
connected_slaves:2
# 从节点详细信息 IP PORT 状态 命令(单位:字节长度)偏移量 延迟秒数
# 主节点每次处理完写操作,会把命令的字节长度累加到master_repl_offset中。
# 从节点在接收到主节点发送的命令后,会累加记录子什么偏移量信息slave_repl_offset,同时,也会每秒钟上报自身的复制偏移量到主节点,以供主节点记录存储。
# 在实际应用中,可以通过对比主从复制偏移量信息来监控主从复制健康状况。
slave0:ip=192.168.10.102,port=6379,state=online,offset=23866,lag=0
slave1:ip=192.168.10.103,port=6379,state=online,offset=23866,lag=0
# master启动时生成的40位16进制的随机字符串,用来标识master节点
master_replid:acc2aaa1f0bb0fd79d7d3302f16bddcbe4add423
master_replid2:0000000000000000000000000000000000000000
# master 命令(单位:字节长度)已写入的偏移量
master_repl_offset:23866
second_repl_offset:-1
# 0/1:关闭/开启复制积压缓冲区标志(2.8+),主要用于增量复制及丢失命令补救
repl_backlog_active:1
# 缓冲区最大长度,默认 1M
repl_backlog_size:1048576
# 缓冲区起始偏移量
repl_backlog_first_byte_offset:1
# 缓冲区已存储的数据长度
repl_backlog_histlen:23866
从节点
127.0.0.1:6379> info replication
# Replication
# 角色
role:slave
# 主节点详细信息
master_host:192.168.10.101
master_port:6379
# slave端可查看它与master之间同步状态,当复制断开后表示down
master_link_status:up
# 主库多少秒未发送数据到从库
master_last_io_seconds_ago:1
# 从服务器是否在与主服务器进行同步 0否/1是
master_sync_in_progress:0
# slave复制命令(单位:字节长度)偏移量
slave_repl_offset:24076
# 选举时,成为主节点的优先级,数字越大优先级越高,0 永远不会成为主节点
slave_priority:100
# 从库是否设置只读,0读写/1只读
slave_read_only:1
# 连接的slave实例个数
connected_slaves:0
# master启动时生成的40位16进制的随机字符串,用来标识master节点
master_replid:acc2aaa1f0bb0fd79d7d3302f16bddcbe4add423
# slave切换master之后,会生成了自己的master标识,之前的master节点的标识存到了master_replid2的位置
master_replid2:0000000000000000000000000000000000000000
# master 命令(单位:字节长度)已写入的偏移量
master_repl_offset:24076
# 主从切换时记录主节点的命令偏移量+1,为了避免全量复制
second_repl_offset:-1
# 0/1:关闭/开启复制积压缓冲区标志(2.8+),主要用于增量复制及丢失命令补救
repl_backlog_active:1
# 缓冲区最大长度,默认 1M
repl_backlog_size:1048576
# 缓冲区起始偏移量
repl_backlog_first_byte_offset:1
# 缓冲区已存储的数据长度
repl_backlog_histlen:24076
6、复制的配置项
从 Redis 2.8 开始, 为了保证数据的安全性, 可以通过配置, 让主服务器只在有至少 N 个当前已连接从服务器的情况下, 才执行写命令。
不过, 因为 Redis 使用异步复制, 所以主服务器发送的写数据并不一定会被从服务器接收到, 因此, 数据丢失的可能性仍然是存在的。
以下是这个特性的运作原理:
- 从服务器以每秒一次的频率 PING 主服务器一次, 并报告复制流的处理情况。
- 主服务器会记录各个从服务器最后一次向它发送 PING 的时间。
- 用户可以通过配置, 指定网络延迟的最大值
min-slaves-max-lag
, 以及执行写操作所需的至少从服务器数量min-slaves-to-write
。
如果至少有 min-slaves-to-write
个从服务器, 并且这些服务器的延迟值都少于 min-slaves-max-lag
秒, 那么主服务器就会执行客户端请求的写操作。
你可以将这个特性看作 CAP 理论中的 C 的条件放宽版本: 尽管不能保证写操作的持久性, 但起码丢失数据的窗口会被严格限制在指定的秒数中。
另一方面, 如果条件达不到 min-slaves-to-write
和 min-slaves-max-lag
所指定的条件, 那么写操作就不会被执行, 主服务器会向请求执行写操作的客户端返回一个错误。
以下是这个特性的两个选项和它们所需的参数:
min-slaves-to-write <number of slaves>
min-slaves-max-lag <number of seconds>
详细的信息可以参考 Redis 源码中附带的 redis.conf
示例文件。
7、主从复制存在的问题
- 一旦 主节点宕机,从节点 晋升成 主节点,同时需要修改 应用方 的 主节点地址,还需要命令所有 从节点 去 复制 新的主节点,整个过程需要 人工干预。
- 主节点 的 写能力 受到 单机的限制。
- 主节点 的 存储能力 受到 单机的限制。
- 原生复制 的弊端在早期的版本中也会比较突出,比如:
Redis
复制中断 后,从节点 会发起psync
。此时如果 同步不成功,则会进行 全量同步,主库 执行 全量备份 的同时,可能会造成毫秒或秒级的 卡顿。
二、redis Sentinel(哨兵)
Redis 哨兵(Sentinel)是 Redis 的高可用性(Hight Availability)解决方案。
Redis 哨兵是 Raft 算法 的具体实现。
在复制的基础上,哨兵实现了 自动化 的 故障恢复。缺陷是 写操作 无法 负载均衡,存储能力 受到 单机 的限制
1、哨兵简介
Redis 哨兵(Sentinel)是 Redis官方的的高可用性(Hight Availability)解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
Sentinel 的主要功能如下:
- 监控,哨兵会不断检查您的 master 实例和 replica 实例是否按预期工作。
- 通知,当受监控的 Redis 实例出现问题时,哨兵可以通过 API 通知系统管理员或其他计算机程序。
- 自动故障转移,如果 master 没有按预期工作,哨兵可以启动一个故障转移过程,其中一个 replica 被提升为 master,其他的副本被重新配置为使用新的 master,应用程序在连接 Redis 服务器时会被告知新的地址。
- 配置提供程序,哨兵会充当客户端服务发现的权威来源:客户端连接到哨兵以获取当前 Redis 主节点的地址。如果发生故障转移,哨兵会报告新地址。
在使用 Redis 哨兵之前,您需要了解一些基础知识:
- 您至少需要三个哨兵实例才能进行稳健的部署。
- 这三个哨兵实例应放置在彼此独立的计算机或虚拟机中。例如,分别位于不同的可用区域上的不同物理服务器或虚拟机上。
- 由于 Redis 使用异步复制,无法保证在发生故障时能够保留已确认的写入。 然而,有一些部署哨兵的方法,可以使丢失写入的窗口限于某些时刻,当然还有其他不太安全的部署方法。
- 如果您不在开发环境中经常进行测试,就无法确保 HA 的设置是安全的。在条件允许的情况,如果能够在生产环境中进行验证则更好。错误的配置往往都是在你难以预期和响应的时间出现(比如,凌晨 3 点你的 master 节点悄然罢工)。
- 哨兵、Docker 或其他形式的网络地址转换或端口映射应谨慎混用:Docker 执行端口重映射,会破坏其他哨兵进程的哨兵自动发现以及 master 的 replicas 列表。
2、启动哨兵
启动一个 Sentinel 可以使用下面任意一条命令,两条命令效果完全相同。
redis-sentinel /path/to/sentinel.conf
redis-server /path/to/sentinel.conf --sentinel
当一个 Sentinel 启动时,它需要执行以下步骤:
- 初始化服务器。
- 使用 Sentinel 专用代码。
- 初始化 Sentinel 状态。
- 初始化 Sentinel 的主服务器列表。
- 创建连向被监视的主服务器的网络连接。
Sentinel 本质上是一个运行在特殊状模式下的 Redis 服务器。
Sentinel 模式下 Redis 服务器只支持 PING
、SENTINEL
、INFO
、SUBSCRIBE
、UNSUBSCRIBE
、PSUBSCRIBE
、PUNSUBSCRIBE
七个命令。
创建连向被监视的主服务器的网络连接,Sentinel 将成为主服务器的客户端,它可以向主服务器发送命令,并从命令回复中获取相关的信息。对于每个被 Sentinel 监视的主服务器,Sentinel 会创建两个连向主服务器的异步网络:
- 命令连接:专门用于向主服务器发送命令,并接受命令回复。
- 订阅连接:专门用于订阅主服务器的
__sentinel__:hello
频道。
3、监控
1、检测服务器状态
Sentinel 向 Redis 服务器发送
PING
命令,检查其状态。
默认情况下,每个 Sentinel
节点会以 每秒一次 的频率对 Redis
节点和 其它 的 Sentinel
节点发送 PING
命令,并通过节点的 回复 来判断节点是否在线。
- 主观下线:主观下线 适用于所有 主节点 和 从节点。如果在
down-after-milliseconds
毫秒内,Sentinel
没有收到 目标节点 的有效回复,则会判定 该节点 为 主观下线。 - 客观下线:客观下线 只适用于 主节点。当
Sentinel
将一个主服务器判断为主管下线后,为了确认这个主服务器是否真的下线,会向同样监视这一主服务器的其他 Sentinel 询问,看它们是否也认为主服务器已经下线。当足够数量的 Sentinel 认为主服务器已下线,就判定其为客观下线,并对其执行故障转移操作。Sentinel
节点通过sentinel is-master-down-by-addr
命令,向其它Sentinel
节点询问对该节点的 状态判断。
2、获取服务器信息
Sentinel 向主服务器发送
INFO
命令,获取主服务器及它的从服务器信息。
- 获取主服务器信息 - Sentinel 默认会以每十秒一次的频率,通过命令连接向被监视的主服务器发送
INFO
命令,并通过分析INFO
命令的回复来获取主服务器的当前信息。- 主服务自身信息:包括 run_id 域记录的服务器运行 ID,以及 role 域记录的服务器角色
- 主服务的从服务器信息:包括 IP 地址和端口号
- 获取从服务器信息 - 当 Sentinel 发现主服务器有新的从服务器出现时,Sentinel 除了会为这个新的从服务器创建相应的实例结构之外,Sentinel 还会创建连接到从服务器的命令连接和订阅连接。
4、通知
对于每个与 Sentinel 连接的服务器,Sentinel 既会向服务器的 __sentinel__:hello
频道发送消息,也会订阅服务器的 __sentinel__:hello
频道的消息。
1、向服务器发送消息
在默认情况下,Sentinel 会以每两秒一次的频率,通过命令向所有被监视的主服务器和从服务器发送以下格式的命令。
PUBLISH __sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"
这条命令向服务器的 __sentinel__:hello
频道发送一条消息。
2、接收服务器的消息
当 Sentinel 与一个主服务器或从服务器建立起订阅连接后,Sentinel 就会通过订阅连接,向服务器发送以下命令:SUBSCRIBE __sentinel__:hello
。
Sentinel 对 __sentinel__:hello
频道的订阅会一直持续到 Sentinel 与服务器断开连接为止。
5、选举 Leader
Redis Sentinel 系统选举 Leader 的算法是 Raft 的实现。
Raft 是一种共识性算法,想了解其原理,可以参考 深入剖析共识性算法 Raft。
当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个 Sentinel 会进行协商,选举出一个领头的 Sentinel,并由领头 Sentinel 对下线主服务器执行故障转移操作。
所有在线 Sentinel 都有资格被选为 Leader。
每个 Sentinel
节点都需要 定期执行 以下任务:
(1)每个 Sentinel
以 每秒钟 一次的频率,向它所知的 主服务器、从服务器 以及其他 Sentinel
实例 发送一个 PING
命令。
(2)如果一个 实例(instance
)距离 最后一次 有效回复 PING
命令的时间超过 down-after-milliseconds
所指定的值,那么这个实例会被 Sentinel
标记为 主观下线。
(3)如果一个 主服务器 被标记为 主观下线,那么正在 监视 这个 主服务器 的所有 Sentinel
节点,要以 每秒一次 的频率确认 主服务器 的确进入了 主观下线 状态。
(4)如果一个 主服务器 被标记为 主观下线,并且有 足够数量 的 Sentinel
(至少要达到 配置文件 指定的数量)在指定的 时间范围 内同意这一判断,那么这个 主服务器 被标记为 客观下线。
(5)在一般情况下, 每个 Sentinel
会以每 10
秒一次的频率,向它已知的所有 主服务器 和 从服务器 发送 INFO
命令。当一个 主服务器 被 Sentinel
标记为 客观下线 时,Sentinel
向 下线主服务器 的所有 从服务器 发送 INFO
命令的频率,会从 10
秒一次改为 每秒一次。
(6)Sentinel
和其他 Sentinel
协商 主节点 的状态,如果 主节点 处于 SDOWN
状态,则投票自动选出新的 主节点。将剩余的 从节点 指向 新的主节点 进行 数据复制。
(7)当没有足够数量的 Sentinel
同意 主服务器 下线时, 主服务器 的 客观下线状态 就会被移除。当 主服务器 重新向 Sentinel
的 PING
命令返回 有效回复 时,主服务器 的 主观下线状态 就会被移除。
::: warning
一个有效的 PING
回复可以是:+PONG
、-LOADING
或者 -MASTERDOWN
。如果 服务器 返回除以上三种回复之外的其他回复,又或者在 指定时间 内没有回复 PING
命令, 那么 Sentinel
认为服务器返回的回复 无效(non-valid
)。
:::
6、故障转移
在选举产生出 Sentinel Leader 后,Sentinel Leader 将对已下线的主服务器执行故障转移操作。操作含以下三个步骤:
(一)选出新的主服务器
故障转移第一步,是 Sentinel Leader 在已下线主服务属下的所有从服务器中,挑选一个状态良好、数据完整的从服务器。然后,向这个从服务器发送 SLAVEOF no one
命令,将其转换为主服务器。
Sentinel Leader 如何选出新的主服务器:
- 删除列表中所有处于下线或断线状态的从服务器。
- 删除列表中所有最近五秒没有回复过 Sentinel Leader 的 INFO 命令的从服务器。
- 删除所有与已下线主服务器连接断开超过
down-after-milliseconds
* 10 毫秒的从服务器(down-after-milliseconds
指定了判断主服务器下线所需的时间)。 - 之后, Sentinel Leader 先选出优先级最高的从服务器;如果优先级一样高,再选择复制偏移量最大的从服务器;如果结果还不唯一,则选出运行 ID 最小的从服务器。
(二)修改从服务器的复制目标
选出新的主服务器后,Sentinel Leader 会向所有从服务器发送 SLAVEOF
命令,让它们去复制新的主服务器。
(三)将旧的主服务器变为从服务器
Sentinel Leader 将旧的主服务器标记为从服务器。当旧的主服务器重新上线,Sentinel 会向它发送 SLAVEOF 命令,让其成为从服务器。
7、部署哨兵集群
角色 | IP | 端口 |
---|---|---|
Master | 192.168.1.10 | 6379 |
Sentinel-01 | 192.168.1.10 | 26379 |
Master | 192.168.1.20 | 6379 |
Sentinel-01 | 192.168.1.20 | 26379 |
Master | 192.168.1.30 | 6379 |
Sentinel-01 | 192.168.1.30 | 26379 |
1、配置和创建服务器的节点和哨兵
# mkdir -p /data/redis_cluster/redis_26379
# mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs}
# vim /opt/redis_cluster/redis_26379/conf/26379.conf
bind 192.168.1.10
port 26379
daemonize yes
logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log
dir /data/redis_cluster/redis_26379
#mymaster主节点别名 主节点 ip 和端口,判断主节点失败,两个sentinel节点同意
sentinel monitor mymaster 192.168.1.10 6379 2
#选项指定了 Sentinel 认为服务器已经断线所需的毫秒数
sentinel down-after-milliseconds mymaster 60000
#向新的主节点发起复制操作的从节点个数,1轮询发起复制
sentinel parallel-syncs mymaster 1
#故障转移超时时间
sentinel failover-timeout mymaster 180000
# rsync -avz /opt/* redis-2:/opt/
# rsync -avz /opt/* redis-3:/opt/
# mkdir -p /data/redis_cluster/redis_26379
# cd /opt/redis_cluster/redis
# make install
# sed -i 's#bind 192.168.1.10#bind 192.168.1.20#g' /opt/redis_cluster/redis_6379/conf/6379.conf
# sed -i 's#bind 192.168.1.10#bind 192.168.1.20#g' /opt/redis_cluster/redis_26379/conf/26379.conf
# mkdir -p /data/redis_cluster/redis_26379
# cd /opt/redis_cluster/redis
# make install
# sed -i 's#bind 192.168.1.10#bind 192.168.1.30#g' /opt/redis_cluster/redis_6379/conf/6379.conf
# sed -i 's#bind 192.168.1.10#bind 192.168.1.30#g' /opt/redis_cluster/redis_26379/conf/26379.conf
::: warning
Docker 能够在主机网络模式下运行。这应该不会产生任何问题,因为在此设置中不会重新映射端口。但是使用带有转发端口的 Docker 运行一组 Sentinel 实例(或任何其他端口被重新映射的 NAT 设置),您可以使用以下两个 Sentinel 配置指令来强制 Sentinel 宣布一个具体的一组IP和端口,并将端口进行暴露。
:::
sentinel announce-ip <ip>
sentinel announce-port <port>
2、配置主从关系
# redis-cli slaveof 192.168.1.10 6379
# redis-cli slaveof 192.168.1.10 6379
3、启动哨兵并查看配置文件
# redis-sentinel /opt/redis_cluster/redis_26379/conf/26379.conf
# redis-sentinel /opt/redis_cluster/redis_26379/conf/26379.conf
# redis-sentinel /opt/redis_cluster/redis_26379/conf/26379.conf
# tail -6 /opt/redis_cluster/redis_26379/conf/26379.conf
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 192.168.1.20 6379
sentinel known-replica mymaster 192.168.1.30 6379
sentinel known-sentinel mymaster 192.168.1.30 26379 bf3ca2e88b7741521ee393db20982c1025808333
sentinel known-sentinel mymaster 192.168.1.20 26379 43626a1048ddeeab42259025e5e6942f4826a5f8
sentinel current-epoch 0
4、哨兵常用命令
# redis-cli -h redis-1 -p 26379
redis-1:26379> Info Sentinel //查看主从信息
redis-1:26379> Sentinel masters //返回被监视的所有master及状态
redis-1:26379> Sentinel master <master name> //查看指定master信息
redis-1:26379> Sentinel slaves <master name> //查看从节点信息(指定)
redis-1:26379> Sentinel sentinels <master name> //查看哨兵信息及状态
redis-1:26379> Sentinel get-master-addr-by-name <master name> //查看当前主节点信息和端口号
redis-1:26379> Sentinel failover <master name> //手动执行故障转移
redis-1:26379> Sentinel flushconfig //如果sentinel.conf丢失,可以使用这个命令生成新的配置文件
5、故障转移
1、查询权重
redis-1:6379> CONFIG GET slave-priority
1) "slave-priority"
2) "100" //默认100
2、从节点设置权重
# redis-cli -h redis-2 -p 6379 CONFIG SET slave-priority 0
# redis-cli -h redis-3 -p 6379 CONFIG SET slave-priority 0
3、强制重新选举
# redis-cli -h redis-1 -p 26379 Sentinel failover mymaster
4、恢复从节点权重
# redis-cli -h redis-2 -p 6379 CONFIG SET slave-priority 100
# redis-cli -h redis-3 -p 6379 CONFIG SET slave-priority 100
评论区