Redis 主从复制与哨兵

Redis 可以使用从属服务器来实现读写分离提高吞吐量或在主服务器故障时接替主服务器以提高可用性。

每个 Redis 服务器实例都可以配置多个 slave 节点,slave 服务器也可以拥有次级 slave 节点, 可以组织成复杂的树状结构(虽说生产环境下极少有人这么做)。

配置主从复制

为了尝试配置主从复制,我们至少需要两个 redis 服务器实例。最简单的方法是在 redis 官网下载 redis-server 二进制可执行文件,分别放在 master 和 slave 目录中。

在每个目录中分别创建 redis.conf 配置文件。master 实例的配置文件采用默认即可, 在 slave 实例中进行主从复制配置:

# 和主服务器 6379 区分 port 6380 # 主服务器 ip 端口 slaveof 127.0.0.1 6379 # 如果主服务器配置了密码请写在这个配置项中 # masterauth <master-password> ## ## 接下来的选项保留默认配置即可,这里仅做介绍 ## # 当与 master 断开连接或正在进行同步时 # yes: 仍然正常响应客户端请求,但可能返回过时数据 # no: 除 INFO 和 SLAVEOF 命令正常外,其它命令均返回 SYNC with master in progress 错误 slave-serve-stale-data yes # 从服务器只读 slave-read-only yes

使用redis-server redis.conf 命令分别启动 redis-server 实例。 使用redis-cli -p 6380命令连接从服务器:

127.0.0.1:6380> info Replication # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:16 master_sync_in_progress:0 slave_repl_offset:3640 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:0b4e100aa9e9fda54aeba2bc110316d811ac2ff6 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3640 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:3640 127.0.0.1:6380> get a 1 127.0.0.1:6380> set a 2 (error) READONLY You can't write against a read only slave.

SLAVEOF host port 可以动态改变从服务器所属的 master 节点。SLAVEOF NO ONE 关闭复制功能,并从 slave 服务器转变回 master 服务器,原来同步所得的数据集不会被丢弃。在当主服务器故障时,可以使用SLAVEOF NO ONE命令将 slave 服务器提升为 master。

主从复制原理 SYNC

在 Redis 2.8 之前的版本里,Redis 仅支持全量复制不支持增量复制,这极大的影响了主从同步的性能。

Redis 2.8 之前的版本主从复制流程如下:

slave 发送 SYNC 命令给 master

master 执行 bgsave 命令生成 rdb 文件。于此同时,所有新的写命令都将被写入复制缓冲区内

master 将 rdb 文件发送给 slave

master 将缓冲区中的命令同步给 slave, 完成一次主从同步

PSYNC

Redis 2.8 开始使用 PSYNC 命令代替 SYNC 命令, PSYNC 具有全量复制和增量复制功能。

master 和 slave 节点均拥有一个 runid 作为自己的唯一标识。

master 和 slave 会各自维护一个复制偏移量,在增量复制时标识同步进度。

master 会维护一个 FIFO 的复制缓冲区(replication backlog),默认大小 1mb。

# 复制缓冲区大小 repl-backlog-size 1mb # 当 master 不再与任何 slave 保持连接时,复制缓冲区可能被清空 # repl-backlog-ttl 用于配置从断开连接到清空缓冲区间隔的秒数 # 0 表示永不清除缓冲区 repl-backlog-ttl 3600

接下来我们可以开始说明 PSYNC 命令执行的流程:

slave 向 master 请求同步

若 slave 未与任何 master 同步过或执行了 SLAVEOF NO ONE 命令,则向 master 发送 PSYNC ? -1命令要求进行全量同步。

否则,则向 master 发送 psync <runid> <offset>命令要求增量同步,其中 runid 是上次同步的主服务器的ID,offset 是同步偏移量

master 响应同步请求

若 slave 请求增量同步且满足:1. runid 与自身相同;2. 同步偏移量处于自身复制缓冲区内,则响应+continue将复制缓冲区内的数据同步到 slave

若 slave 请求增量同步但不同时满足上述两个条件或 slave 请求全量同步, 则响应+fullresync <runid> <offset> 执行全量同步,其中 runid 是自身ID, offset 是自身同步偏移量。

若自身版本过低不支持PSYNC命令则响应 error, slave 会尝试使用 SYNC 命令进行同步。

哨兵

简单的主从复制架构在 master 故障后会不可用,Redis 官方提供了哨兵(sentinel)机制自动实现主备切换保证高可用。

哨兵机制通过一组哨兵节点监控主从节点的运行状态,并在主节点故障后选举新的主节点。

哨兵节点定时执行3个任务:

哨兵节点每隔10s向主从节点发送INFO命令以更新拓扑图,自动感知新的 slave 节点。

哨兵节点每隔1s向主从节点发送PING命令进行心跳检测。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b154e0805041b8c2ad4513279bc6abd1.html