主备原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了主备原理相关的知识,希望对你有一定的参考价值。

参考技术A 备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接。一个事务日志同步的完整过程是这样的:

1、在备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从哪个位置开始请求 binlog,这个位置包含文件名和日志偏移量。

2、在备库 B 上执行 start slave 命令,这时候备库会启动两个线程,就是图中的 io_thread 和 sql_thread 。其中 io_thread 负责与主库建立连接。

3、主库 A 校验完用户名、密码后,开始按照备库 B 传过来的位置,从本地读取 binlog, 发给 B(push模式) 。

4、备库 B 拿到 binlog 后,写到本地文件,称为中转日志( relay log )。

5、sql_thread 读取中转日志,解析出日志里的命令,并执行。

这里需要说明,后来由于多线程复制方案的引入, sql_thread 演化成为了多个线程。

binlog 的三种格式对比:

一种是 statement,按语句进行数据备份,可能需要联系上下文,日志相对较少 ,一种是 row,按行记录对数据的修改,无需关心sql语句或者上下文,逻辑简单,日志文件巨大,性能相对较低 。还有第三种格式,叫作 mixed ,其实它就是前两种格式的 混合 。

show variables like ' binlog_format '; 该参数控制。

1、因为有些 statement 格式的 binlog 可能会导致主备不一致 ,所以要使用 row 格式。

2、但 row 格式的缺点是, 很占空间 。比如你用一个 delete 语句删掉 10 万行数据,用 statement 的话就是一个 SQL 语句被记录到 binlog 中,占用几十个字节的空间。但如果用 row 格式的 binlog,就要把这 10 万条记录都写到 binlog 中。这样做,不仅会占用更大的空间,同时写 binlog 也要耗费 IO 资源,影响执行速度。

3、mysql 就取了个折中方案,也就是有了 mixed 格式的 binlog。mixed 格式的意思是,MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用 row 格式,否则就用 statement 格式。也就是说,mixed 格式可以利用 statment 格式的优点,同时又避免了数据不一致的风险。

越来越推荐row格式,因为它方便恢复数据 。

备库: show slave status\G  查看备库情况, seconds_behind_master 主备延时,理想状况为0.

1、机器异构,备库性能差或者集中在一个机器上。

2、忽视备库压力,对备库使用没有节制,比如复杂的读计算。

1、一主多从。除了备库外,可以多接几个从库,让这些从库来分担读的压力。

2、通过 binlog 输出到外部系统,比如 Hadoop 这类系统,让外部系统提供统计类查询的能力。

在主库上,影响并发度的原因就是各种锁了。

在备库上,就是图中备库上 sql_thread 更新数据 (DATA) 的逻辑。如果是用 单线程 的话,就会导致备库应用日志不够快,造成主备延迟。

官方 MySQL5.6 版本 ,支持了并行复制,只是支持的粒度是 按库并行 。这个策略的并行效果,取决于压力模型。如果在主库上有多个 DB,并且 各个 DB 的压力均衡 ,使用这个策略的效果会很好。

相比于 按表 和 按行 分发,这个策略有两个优势:

1、构造 hash 值的时候很快,只需要库名;而且一个实例上 DB 数也不会很多,不会出现需要构造 100 万个项这种情况。

2、不要求 binlog 的格式。因为 statement 格式的 binlog 也可以很容易拿到库名。

但是,如果你的主库上的表都放在同一个 DB 里面,这个策略就没有效果了;或者如果不同 DB 的热点不同,比如一个是业务逻辑库,一个是系统配置库,那也起不到并行的效果。

理论上你可以创建不同的 DB,把相同热度的表均匀分到这些不同的 DB 中,强行使用这个策略。不过据我所知,由于需要特地移动数据,这个策略用得并不多。

在 MariaDB 并行复制实现之后, 官方的 MySQL5.7 版本也提供了类似的功能,由参数 s lave-parallel-type 来控制并行复制策略:

1、配置为 DATABASE ,表示使用 MySQL 5.6 版本的按库并行策略;

2、配置为 LOGICAL_CLOCK ,表示的就是类似 MariaDB 的策略。不过,MySQL 5.7 这个策略,针对并行度做了优化。这个优化的思路也很有趣儿。

在 2018 年 4 月份发布的 MySQL 5.7.22 版本里,MySQL 增加了一个新的并行复制策略,基于 WRITESET 的并行复制。

相应地,新增了一个参数 binlog-transaction-dependency-tracking ,用来控制是否启用这个新策略。这个参数的可选值有以下三种。

1、COMMIT_ORDER,表示的就是前面介绍的,根据同时进入 prepare 和 commit 来判断是否可以并行的策略。

2、WRITESET,表示的是对于事务涉及更新的每一行,计算出这一行的 hash 值,组成集合 writeset。如果两个事务没有操作相同的行,也就是说它们的 writeset 没有交集,就可以并行。

3、WRITESET_SESSION,是在 WRITESET 的基础上多了一个约束,即在主库上同一个线程先后执行的两个事务,在备库执行的时候,要保证相同的先后顺序。

当然为了唯一标识,这个 hash 值是通过“库名 + 表名 + 索引名 + 值”计算出来的。如果一个表上除了有主键索引外,还有其他唯一索引,那么对于每个唯一索引,insert 语句对应的 writeset 就要多增加一个 hash 值。

你可能看出来了,这跟我们前面介绍的基于 MySQL 5.5 版本的按行分发的策略是差不多的。不过,MySQL 官方的这个实现还是有很大的优势:

writeset 是在主库生成后直接写入到 binlog 里面的,这样在备库执行的时候,不需要解析 binlog 内容(event 里的行数据),节省了很多计算量;

不需要把整个事务的 binlog 都扫一遍才能决定分发到哪个 worker,更省内存;

由于备库的分发策略不依赖于 binlog 内容,所以 binlog 是 statement 格式也是可以的。

因此,MySQL 5.7.22 的并行复制策略在通用性上还是有保证的。

当然,对于“表上没主键”和“外键约束”的场景,WRITESET 策略也是没法并行的,也会暂时退化为单线程模型。

图中,虚线箭头表示的是主备关系,也就是 A 和 A’互为主备, 从库 B、C、D 指向的是主库 A。一主多从的设置,一般用于读写分离,主库负责所有的写入和一部分读,其他的读请求则由从库分担。

HA主备路由模式的原理

    HA是High Availability缩写,即高可用性 ,可防止网络中由于单个防火墙的设备故障或网络故障导致网络中断,保证网络服务的连续性和安全强度。目前,ha功能已经是防火墙内一个重要组成部分。
        主备模式(Active-standby):在一个冗余组中,有两台防火墙,一台处于主状态。在这个状态下,防火墙响应ARP请求,并且转发网络流量;另一台处于备份状态,该防火墙不响应ARP请求,也不转发网络流量。主备之间同步状态信息,当主墙down机或网线故障时,进行主备切换。
        主主模式(Active-active): 在一个冗余组中,有两台防火墙,两台都处于主状态。两台防火墙都响应ARP请求,并且转发网络流量;主主之间同步状态信息,当一主墙down机或网线故障时,进行切换,由另一主墙转发网络流量。提高了数据包处理的吞吐量,平衡了网络负载,优化了网络性能。
        NGFW的HA功能只支持两台设备。在nat/路由模式和桥接模式下支持主主和主备两种工作模式。HA功能要求两台设备的型号相同、组网方式相同、软件版本一致。在以上条件不一致的情况下,HA功能有可能失效。
        两台HA设备之间同步信息和通讯信息采用专用的以太网口,称为HA接口。HA接口连接方式为直连。为了维护HA状态的正确性和报文同步,必须妥善维护接口的连接。HA接口的任何中断都可能导致不可预测的后果:比如两台设备可能同时工作状态(处于主备工作状态时),若重新连接之后,两台设备重新开始HA启动过程。

以上是关于主备原理的主要内容,如果未能解决你的问题,请参考以下文章

2--Master主备切换机制原理剖析与源码分析

HA主备路由模式的原理

笔记 VRRP基本原理 主备备份 负载均衡

redis演练 redis复制(主备模式)

MySQL高可用之主备同步:MySQL是如何保证主备一致的

网络知识点防火墙主备冗余技术