Redis Replication 原理是实践

Redis 的高可用策略包括持久化,复制,哨兵和集群,本文讲解redis的复制策略.一般redis的单机QPS可以轻松过万,对于一般的系统足够了,但对于一些高并发的场景,比如商品详情页这种读多写少的应用,QPS可能会达到十万百万,但写操作甚少.为了使Redis缓存满足需求,需求对其进行水平扩展.

redis replication 简介

redis 采用master/slave架构,用异步方式复制数据到slave节点,master节点可以配置多个 salve 节点,slave节点只能有一个master,slave 节点也可以作为其他slave节点的master.
Redis 复制可以起到热备份,故障恢复,负载均衡等作用,复制也是哨兵和集群模式的基础.

复制流程

连接建立阶段
  1. slave节点运行 slaveof 命令, 会首先读取配置文件中的 master 节点的信息并保存在masterhost和maserport字段中
  2. slave 节点定时任务每秒检查是否有 master 节点可以连接,如果有,就与 master 节点建立连接并建立一个处理复制工作的文件事件处理器
  3. slave 节点发送心跳 ping 给 master 节点,如果收到了 pong 相应,则继续复制过程,否则需要重连
  4. 如果 master 设置了 requirepass,那么 salve 节点必须发送 masterauth 的口令过去进行认证,如果认证不通过,则断开重连
数据同步阶段
  1. salve 向 master 发送 psync runid offset 命令(2.8版本以前是 sync 命令)
  2. master 根据收到的 runid 决定是全量复制还是部分复制,如果是部分复制,则根据 offset 确定从何处开始复制
命令复制阶段
  1. master 将写操作的命令发送给 slave, 同时写入 backlog 缓存
  2. slave 接收到写操作命令并执行,复制完成.

全量复制

  1. 初次复制或者由于主机重启等原因,进行全量复制
  2. master 接到全量复制的命令后,执行bgsave, 在后台生成一份 rdb 文件,并开启一个缓冲区记录新的写操作
  3. master 将 rdb 文件发送给 salve, slave 清空旧数据并载入新数据
  4. master 将缓冲区中记录的新的写命令发送给 slave 并执行

部分复制

在正常复制过程中,假设 master和slave 网络连接断掉,当 salve 重连 master 时,会触发部分复制.

从redis 2.8开始,支持部分复制,master和slave会维护一个offset,master 在复制过程中会同时把数据缓存到backlog中,包括offset,当连接中断重连后,master 根据 slave 发送的 psync 中的 offset 找到上次中断的位置并从这里开始复制

redis复制中的一些核心概念

  • 复制过程中,master和salve会维护一个offset, slave 每秒都会向 master 报告自己offset,offset 起到维护数据一致的作用
  • master 在同步数据给 salve 的时候,会同时将数据写在本地的 backlog 中,backlog 用于中断重连后的增量复制
  • master 节点维护了一个 runid, salve 根据 runid 判断是否进行全量复制,redis重启后runid 会发生变化,如果不希望变,可以使用 redis-cli debug reload 重启
  • slave 节点运行 psync runid offset 向 master 请求复制, 如果runid为-1或与 master 的runid不同,则会出发全量复制
  • master 和 slave 节点会互相发送心跳检测,master每隔10s发一次,slave每秒发一次

配置

配置项说明

从节点配置
配置项 说明
slaveof 在redis启动时指定master建立主从关系,可以在配置文件中配置,也可以启动后在命令行中配置
repl-timeout 60 主从节点连接超时阈值
slave-read-only yes 从节点是否设置为只读
slave-serve-stale-data yes 当从节点与主节点失去联系的时候,是否还能处理请求。默认yes表示可以,如果对数据一致性要求比较高,应该设置为no,这样从节点就只能响应 info, slaveof 等少数命令
主节点配置
配置项 说明
repl-diskless-sync no 无硬盘复制,表示在全量复制阶段,数据只写入内存,不写入文件
repl-diskless-sync-delay 5 开启无硬盘复制后,这个参数才生效, 表示开始复制前等待的时间,这个等待是为了让所有salve都完成连接,因为复制开始后,新的slave连接要等到前面所有的slave传输完成后才能开始复制。
client-output-buffer-limit slave 256MB 64MB 60 配置全量复制时主节点的缓冲区大小
repl-disable-tcp-nodelay no 设置为yes时,TCP会对包进行合并从而减少带宽,但是发送的频率会降低,从节点数据延迟增加,一致性变差
masterauth 从节点身份验证
repl-ping-slave-period 10 ping命令间隔
repl-backlog-size 1mb 复制积压缓冲区,命令复制给slave的同时会存到backlog中,为了避免因为网络中断引起的全量复制
repl-backlog-ttl 3600 当主节点没有从节点时,复制积压缓冲区保留的时间
min-slaves-to-write 3 最少的处于连接状态的从节点数目
min-slaves-max-lag 所有从节点延迟超时的阈值,与 min-slaves-to-write 3 同时使用,可以避免数据丢失

完整配置过程

准备三个节点
ip 角色
172.17.0.2 master
172.17.0.3 slave
172.17.0.4 slave
修改配置文件

修改master配置文件:

1
2
bind 0.0.0.0  # 允许任意ip连接
protected-mode no # 关闭安全模式

修改两个slave配置文件:

1
salveof 172.17.0.2 6379
启动三个Redis服务器观察效果

image

文章标题:Redis Replication 原理是实践

文章字数:1.5k

本文作者:Waterandair

发布时间:2017-11-15, 23:38:23

最后更新:2019-12-28, 14:03:59

原始链接:https://waterandair.github.io/2017-11-15-redis-replication.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

github