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 之前的版本主从复制流程如下:

  1. slave 发送 SYNC 命令给 master
  2. master 执行 bgsave 命令生成 rdb 文件。于此同时,所有新的写命令都将被写入复制缓冲区内
  3. master 将 rdb 文件发送给 slave
  4. 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 命令执行的流程:

  1. slave 向 master 请求同步

    1. 若 slave 未与任何 master 同步过或执行了 SLAVEOF NO ONE 命令,则向 master 发送 PSYNC ? -1命令要求进行全量同步。
    2. 否则,则向 master 发送 psync <runid> <offset>命令要求增量同步,其中 runid 是上次同步的主服务器的ID,offset 是同步偏移量
  2. master 响应同步请求
    1. 若 slave 请求增量同步且满足:1. runid 与自身相同;2. 同步偏移量处于自身复制缓冲区内,则响应+continue将复制缓冲区内的数据同步到 slave
    2. 若 slave 请求增量同步但不同时满足上述两个条件或 slave 请求全量同步, 则响应+fullresync <runid> <offset> 执行全量同步,其中 runid 是自身ID, offset 是自身同步偏移量。
  3. 若自身版本过低不支持PSYNC命令则响应 error, slave 会尝试使用 SYNC 命令进行同步。

哨兵

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

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

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

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

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

  • 哨兵节点每隔2s向__sentinel__:hello频道发送自身哨兵节点信息和自身了解的 master 信息。所有哨兵节点均会订阅该频道,并以此更新哨兵集群信息。

若哨兵节点发现 master 节点心跳响应超时,则认为 master 主观下线。此时,master 可能真的已经崩溃也可能仅仅是此哨兵节点与 master 之间出现网络故障。

认为 master 主观下线的哨兵会向其它哨兵发送sentinel is-master-down-by addr询问 master 是否下线。若半数以上的哨兵认为 master 已经下线则认为 master 客观下线。

哨兵节点会选举自己第一个收到的 is-master-down-by 命令的发送者为哨兵领导者。若某一个节点得到过半投票则会成为哨兵领导者,若没有节点得到半数以上票则会进入下一轮投票。此选举流程与 Paxos 算法类似。

哨兵领导者负责选择一个slave节点提升为新 master 节点, 选择逻辑为:

  1. 过滤掉不健康的 slave 节点
  2. 选择 slave-priority 配置值最小的从节点。若有多个从节点 slave-priority 最小且相同则进入下一步
  3. 选择复制偏移量最大的从节点,这意味着这个从节点上面的数据最完整。若仍有多个 slave 节点偏移量相同则进入下一步
  4. 选择 runid 最小的从节点

新的 master 节点选出后会执行提升流程:

  1. 向新选出的 master 节点发出 SLAVEOF NO ONE 命令,提升为新的 master 节点
  2. 向其它 slave 节点发出 SLAVEOF 命令跟随新的 master 节点
  3. 在哨兵集群中将下线的 master 节点更新为下线的 slave 节点,在其回复后命令其跟随新的 master

Redis 主从复制与哨兵的更多相关文章

  1. Linux基于Docker的Redis主从复制、哨兵模式搭建

    本教程基于CentOS7,开始本教程前,请确保您的Linux系统已安装Docker. 1.使用docker下载redis镜像 docker pull redis 安装完成后,使用docker imag ...

  2. Redis——(主从复制、哨兵模式、集群)的部署及搭建

    Redis--(主从复制.哨兵模式.集群)的部署及搭建 重点: 主从复制:主从复制是高可用redis的基础,主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复. 哨兵和集群都是 ...

  3. redis主从复制和哨兵机制

    redis主从复制和哨兵机制 技术标签: redis 1.redis主从复制(master/slave模式) 主数据库可以进行读写操作,当写操作导致数据发生变化时会自动将数据同步给从数据库.而一般情况 ...

  4. Redis系列八:redis主从复制和哨兵

    一.Redis主从复制 主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性 1. 主从复制的相关操作 a,配置主从复制方式一.新增redis6380.conf, ...

  5. redis学习三,Redis主从复制和哨兵模式

    Redis主从复制 java架构师项目实战,高并发集群分布式,大数据高可用,视频教程 1.Master可以拥有多个slave 2.多个slave可以连接同一个Master外,还可以连接到其他的slav ...

  6. redis 主从复制和哨兵模式(二)

    Redis 主从复制 为了分担单机 redis 的数据服务压力,需要进行读写分离,所以搭建 redis 的主从结构,主节点负责写,从节点负责读,主节点定期把数据同步到从节点. 配置主从 # 配置文件中 ...

  7. Redis主从复制配置+哨兵模式

    架构设计: master:s0 slave:s1.s2 主机映射信息如下: 192.168.32.100 s0 192.168.32.101 s1 192.168.32.102 s2 1.安装Redi ...

  8. redis主从复制和哨兵

    摘自:https://www.cnblogs.com/leeSmall/p/8398401.html 一.Redis主从复制 主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点 ...

  9. redis主从复制与哨兵高可用

    redis主从复制 话不多说,直接看案例: 环境准备, 主从规划 主节点:6380 从节点:6381.6382 运行3个redis数据库,达到 1主 2从的配置 #主库 6379.conf port ...

  10. Redis主从复制、哨兵模式

    1.部署主从 环境:主IP:10.0.0.15,端口6379;从IP:10.0.0.16,端口6379. 原理:基于RDB持久化的功能来实现主从复制的功能. a.linux-redis1(10.0.0 ...

随机推荐

  1. c++中的虚函数是什么东西?

    #include <iostream> #include<string> #include<vector> using namespace std; class A ...

  2. [BJOI2017]魔法咒语

    Description Chandra 是一个魔法天才. 从一岁时接受火之教会洗礼之后, Chandra 就显示出对火元素无与伦比的亲和力,轻而易举地学会种种晦涩难解的法术.这也多亏 Chandra ...

  3. LVS实现负载均衡

    三台主机模拟 sishen_63(分发器): eth0(Bridge):192.168.1.63 eth1(vmnet4):192.168.2.63 sishen_64(RealServer1): e ...

  4. [转]2010 Ruby on Rails 書單 與 練習作業

    原帖:http://wp.xdite.net/?p=1754 ========= 學習 Ruby on Rails 最快的途徑無非是直接使用 Rails 撰寫產品.而這個過程中若有 mentor 指導 ...

  5. 动手实现 Redux(四):共享结构的对象提高性能

    接下来两节某些地方可能会稍微有一点点抽象,但是我会尽可能用简单的方式进行讲解.如果你觉得理解起来有点困难,可以把这几节多读多理解几遍,其实我们一路走来都是符合“逻辑”的,都是发现问题.思考问题.优化代 ...

  6. android开发学习 ------- 【转】EventBus的学习理解

    EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间.组件与后台线程间的通信. 比如请求网络,等网络返回时通过Handler或Broadca ...

  7. 第一个 swift 项目

    今天 学习了 一丢丢 swift,特此记录一下 ! 原来创建的时候 ,只要把 语言 由以前的Object-C改为Swift,变创建好了自己的swift工程 第一个简单的swift demo 上代码 i ...

  8. Java GUI 基础组件

    1.JLabel  标签 构造函数: JLabel() JLabel(String text) JLabel(String text,int align)     //第二个参数设置文本的对齐方式,常 ...

  9. CF982C Cut 'em all!

    思路: 在深搜过程中,贪心地把树划分成若干个连通分支就可以了.划分的条件是某个子树有偶数个节点.注意到在一次划分之后并不需要重新计数,因为一个数加上一个偶数并不影响这个数的奇偶性. 实现: #incl ...

  10. sql server 2012 从删库到跑路

    问题: 向sql server 2012单个数据库中导入1500万+条数据的时候,报错: 错误 0xc0202009: 数据流任务 1: SSIS 错误代码 DTS_E_OLEDBERROR.出现 O ...