Redis Replication 原理是实践
Redis 的高可用策略包括持久化,复制,哨兵和集群,本文讲解redis的复制策略.一般redis的单机QPS可以轻松过万,对于一般的系统足够了,但对于一些高并发的场景,比如商品详情页这种读多写少的应用,QPS可能会达到十万百万,但写操作甚少.为了使Redis缓存满足需求,需求对其进行水平扩展.
redis replication 简介
redis 采用master/slave架构,用异步方式复制数据到slave节点,master节点可以配置多个 salve 节点,slave节点只能有一个master,slave 节点也可以作为其他slave节点的master.
Redis 复制可以起到热备份,故障恢复,负载均衡等作用,复制也是哨兵和集群模式的基础.
复制流程
连接建立阶段
- slave节点运行 slaveof 命令, 会首先读取配置文件中的 master 节点的信息并保存在masterhost和maserport字段中
- slave 节点定时任务每秒检查是否有 master 节点可以连接,如果有,就与 master 节点建立连接并建立一个处理复制工作的文件事件处理器
- slave 节点发送心跳 ping 给 master 节点,如果收到了 pong 相应,则继续复制过程,否则需要重连
- 如果 master 设置了 requirepass,那么 salve 节点必须发送 masterauth 的口令过去进行认证,如果认证不通过,则断开重连
数据同步阶段
- salve 向 master 发送 psync runid offset 命令(2.8版本以前是 sync 命令)
- master 根据收到的 runid 决定是全量复制还是部分复制,如果是部分复制,则根据 offset 确定从何处开始复制
命令复制阶段
- master 将写操作的命令发送给 slave, 同时写入 backlog 缓存
- slave 接收到写操作命令并执行,复制完成.
全量复制
- 初次复制或者由于主机重启等原因,进行全量复制
- master 接到全量复制的命令后,执行bgsave, 在后台生成一份 rdb 文件,并开启一个缓冲区记录新的写操作
- master 将 rdb 文件发送给 salve, slave 清空旧数据并载入新数据
- 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 | bind 0.0.0.0 # 允许任意ip连接 |
修改两个slave配置文件:
1 | salveof 172.17.0.2 6379 |
启动三个Redis服务器观察效果
文章标题: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" 转载请保留原文链接及作者。