主从库集群

Redis 提供了主从库模式,以保证数据副本的一致,在从库执行一下命令可以建立主从库关系:

replicaof <dst ip> <dst port>

Redis 的主从库之间采用的是读写分离的方式:

  1. 读操作:主库、从库都可以接收;
  2. 写操作:到主库执行,然后将写操作同步给从库。

写操作只在主库执行,主要是为了避免多实例写导致的数据一致性问题,减少多实例之间数据一致的协商开销。

主从同步是如何进行的

下图是主从第一次同步的流程:

第一阶段

第一阶段,从库会给主库发送 psync 命令,类似 tcp 的握手,该命令有两个参数:主库的 runid 和复制进度 offset。

  • runid 是每个 Redis 实例启动时都会自动生成的一个随机 ID,用来标记这个实例。从库第一次和主库同步时,不知道主库的 runid ,所以将 runid 设置为 “?”;
  • offset 是从库到目前为止处理的偏移量,第一次同步的时候会传 -1 。

收到 psync 命令后,主库会用 FULLRESYNC 响应带上主库 id 和当前的复制进度 offset 返回给从库,从库会记录这两个参数。

第二阶段

主库在收到 psync 后,会执行 bgsave 命令,生成 RDB 文件,然后将文件发送给从库。从库收到文件后,会先情况当前的数据,然后加载 RDB 文件。

第三阶段

在从库处理完 RDB 文件时,主库会将期间处理的写操作放在 replication buffer 中,等到从库处理完 RDB 文件后,主库会将修改操作都发送给从库执行,从而完成主从同步。

基于长连接的命令传播

主从库的连接建立成功,并且完成第一次的全量同步之后,主从库之间会维持一个长链接,主库会将之后接收到的写操作同步给从库。

增量同步

在使用过程中,可能会出现主从库之间网络闪断的情况,如果恢复连接后采用全量同步的方式,必然会有很大的开销。Redis 2.8 之后,采用增量同步的方式来完成这个操作。

当主从断连之后,主库会把期间收到的写操作命令写入 replication buffer,同时也会把这些操作命令也写入 repl_backlog_buffer 这个缓冲区。

repl_backlog_buffer 是一个环形缓冲区,主库会记录自己的偏移量 master_repl_offset,从库会记录自己的偏移量 slave_repl_offset。用命令 info Replication 可以查看对应的 offset。

主从库恢复连接后,从库会用 psync 发送自己的 slave_repl_offset 给主库,主库对比自己的 master_repl_offset ,将两个 offset 之间的写操作同步给从库。

因为 repl_backlog_buffer 是一个环形队列,所以,如果从库的读取速度比较慢,就有可能导致从库还未读取的操作被主库新写的操作覆盖,如果主库接收从库的 psync 时发现从库的 offset 已经被覆盖,为了不丢失数据那么就会发起全量同步。为了避免全量同步,这时候就需要增加 repl_backlog_size 的值,这个值和缓冲空间大小有关,缓存空间大小 = 主库写入命令速度 * 操作大小 - 主从库间网络传输命令速度 * 操作大小 。考虑到突发压力,通常 repl_backlog_size 会设置为 计算结果的 2 到 4 倍。

级联主从

如果一个主库下有很多的从库,这些从库都要和主库进行全量同步的时候,主库的压力会非常大,忙于 fork 子进程生成 RDB 文件,影响主线程处理客户端请求。这是可以将主从结构改成主→ 从 → 从 的联机结构,缓解主库的压力。

实验

我们可以用 docker-compose 实验 Redis 主从同步:

version: "3"
services:
redis-master:
image: redis:7
ports:
- "16379:6379"
container_name: "redis-master"
command: redis-server
networks:
- redis-replica
redis-slave-1:
image: redis:7
ports:
- "6380:6379"
container_name: "redis-slave-1"
command: redis-server --replicaof redis-master 6379
depends_on:
- redis-master
networks:
- redis-replica
redis-slave-2:
image: redis:7
ports:
- "6381:6379"
container_name: "redis-slave-2"
command: redis-server --replicaof redis-slave-1 6379
depends_on:
- redis-slave-1
networks:
- redis-replica
networks:
redis-replica:

这里定义了一个主库 redis-master 以及两个从库 redis-slave-1、redis-slave-2。它们是一个级联的主从关系 redis-master ← redis-slave-1 ← redis-slave-2

我预先在 master 中插入了一些数据之后在设置了两个 slave 节点。启动之后,可以看到 slave2 先向 salve1 发起了同步请求,但是 slave1 还没和 master 完成同步,所以 salve2 一直在重试,直到 salve1 和 master 完成同步后才开始 slave2 和 salve1 之间的数据同步。

Redis-浅谈主从同步的更多相关文章

  1. Redis哨兵模式主从同步不可以绑定127.0.0.1或者0.0.0.0,不然无法进行主从同步

    Redis哨兵模式主从同步不可以绑定127.0.0.1或者0.0.0.0,不然无法进行主从同步,一定要绑定内网IP,而对于跨机房的问题,可以使用iptables进行nat转发来解决.

  2. redis持久化和主从同步

    redis持久化rdb与aof 简介 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的 ...

  3. Linux下的redis的持久化,主从同步及哨兵

    redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失, 为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. RDB持久 ...

  4. redis学习笔记——主从同步(复制)

    在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器进行复 ...

  5. redis 分布式,主从同步

    redis和memcache比较像的,memcache可以实现服务器的集群,redis肯定也是可以的.下面在一台机,实现redis主从复制. 1,copy一下redis.conf,生成一个从机的配置 ...

  6. 浅谈利用同步机制解决Java中的线程安全问题

    我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等 ...

  7. 浅谈ajax同步、异步的问题

    最近实习的时候看到过firefox的同步.异步的警告,想着概念不是那么清楚,于是整理了一下ajax同步异步方面的知识.我是小白,做个笔记. 首先就是概念问题,ajax根据async进行区分同步和异步过 ...

  8. redis 浅谈事务

    写在前面的话 之前在某个网站上看到一个问题:redis在什么情况下出现事务不会滚的情况,以此为由并结合redis官方文档整理这边笔记.不足之处,请指出,谢谢. 事务 redis支持事务,提供两条重要的 ...

  9. 浅谈MySQL同步到ElasticSearch的几种方式及其优缺点

    同步双写 优点:业务逻辑简单. 缺点: 硬编码,有需要写入mysql的地方都需要添加写入ES的代码: 业务强耦合: 存在双写失败丢数据风险: 性能较差:本来mysql的性能不是很高,再加一个ES,系统 ...

随机推荐

  1. 陈胡:Apache SeaTunnel实现 非CDC数据抽取实践

    导读: 随着全球数据量的不断增长,越来越多的业务需要支撑高并发.高可用.可扩展.以及海量的数据存储,在这种情况下,适应各种场景的数据存储技术也不断的产生和发展.与此同时,各种数据库之间的同步与转化的需 ...

  2. Spring Boot配置全局异常捕获

    1 SpringBoot配置全局的异常捕获 项目的说明 配置thymeleaf作为视图模板 ExceptionController.java模拟测试用 MyAjaxExceptionHandler.j ...

  3. 场景实践:使用RDS和ECS搭建个人博客

    体验简介 本教程将使用一台基础环境为CentOS7.7的云服务器ECS实例, 搭配您已有的云数据库RDS实例,帮助您快速搭建属于自己的云上博客. 背景知识 本场景主要涉及以下云产品和服务: 阿里云关系 ...

  4. find-文件搜索

    根据条件搜索文件. 语法 find 目录 [选项] 选项 -name <filename> 按文件目录名查找.文件目录名可使用通配符"*",即表示模糊匹配所有字符. - ...

  5. 微信小程序开发 记录

    采坑了 微信小程序--TabBar不出现的一种原因 学习微信小程序中,遇到底部的TabBar不出现的问题.经过多番尝试,终于解决问题.在此记录问题产生的原因和对策.下面先描述错误现象,接着指出错误原因 ...

  6. [杂项]从子域名接管到Subtaker

    子域名接管安全性分析及落地化 能说只是为了学Go嘛?33333 Github项目直通车 简介 子域名接管,主要原因归结于失效dns记录未删除. 譬如,一条指向test.sec.com的CNAME记录未 ...

  7. 30款提升组织效能 SaaS 工具,我们的宝藏工具箱大公开

    熟悉 Juicedata 的小伙伴知道,从2017年成立到第一款产品发布.从寻找PMF(Product Market Fit) 到开源,我们一直保持着一个精简的团队配置,不少人都很好奇我们是如何做到的 ...

  8. 《Unix 网络编程》15:Unix 域协议

    Unix 域协议 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ 本 ...

  9. 看看CabloyJS是如何实现编辑页面脏标记的

    应用场景 我们在使用Word.Excel时,当修改了内容之后在标题栏会显示脏标记,从而可以明确的告知用户内容有变动.此外,如果在没有保存的情况下关闭窗口,系统会弹出提示框,让用户选择是否放弃修改 那么 ...

  10. NPM Error:gyp: No Xcode or CLT version detected!

    问题 最近在macOS Catalina中使用npm安装模块,经常会出现如下错误: > node-gyp rebuild No receipt for 'com.apple.pkg.CLTool ...