MySQL高可用架构探秘:主从复制剖析、切换策略、延迟优化与架构选型

MySQL高可用的基石

在分布式系统中,单机节点在发生故障时无法提供服务,这可能导致长期的服务不可用,从而影响其他节点的运作,导致的后果非常严重

为了满足服务的高可用,往往是通过节点冗余(新增相同功能的从节点),当发生故障时进行主从切换,让从节点成为新的主节点来继续提供服务

比如:MySQL的主从、Redis的主从、MQ broker的主从...思想大体类似的

作为高可用的基石——主从架构功不可没,本篇文章就来聊聊MySQL的主从的一些细节

image.png

binlog

binlog作为逻辑上恢复数据的日志,是主从数据同步、数据恢复的基础

binlog分为三种格式:statement、row、mixed

statement :记录写操作的SQL,语句轻量、传输快,使用该格式可能会导致数据不一致(因为从机与主机所处的环境不同,比如从机时间与主机不同时,使用now()函数)

row : 记录数据的修改,数据量大、传输慢,误操作时可以恢复数据(反向操作),主从同步时数据一致

mixed :结合statement、row的优点,自动混合选择格式

大多数情况下都是选择格式为row,因为数据一致并且可以恢复数据

主从复制

往期文章中说过当收到写操作需要修改数据时,为了满足数据的一致性,会写undo log(原子性)、redo log(持久性)、binlog等日志

当主节点接收到写操作更改数据时,也需要对从节点进行数据的修改以此来达到数据一致

在主从复制数据依靠的就是binlog,大致流程分为三个阶段:

  1. 主节点dump线程监听binlog变动通知从节点
  2. 从节点使用IO线程接收binlog并将其写入本地 relay log(中继日志)
  3. 从节点使用SQL线程根据relay log恢复数据

image.png

在单机中写完日志即可提交事务响应,而在主从中根据响应阶段的不同,主从复制的方式分为多种:

同步复制:所有从节点都响应(恢复完数据)主节点才响应,性能差、数据强一致

异步复制:主节点通知完从节点就立马响应,性能最好,存在延迟有数据一致性问题

半同步复制:只要有一个从节点响应主节点就响应,一主一从下与同步复制一致,网络超时退化为异步复制

增强半同步复制:在半同步复制的基础上,主节点收到响应后才提交事务,数据一致性会比半同步好,但性能稍差

延迟复制:从节点延迟一段时间恢复数据,这样即使发生误操作也可以进行回滚数据

主从切换

当主机发生故障时需要将从机切换为主机

不同策略

一般中间件的主从切换都只能在CAP理论中满足其二,即在分区容错(P)下只能满足可靠(C)或可用(A)

binlog上会记录主节点写操作的时间,从节点会维护一个 seconds_behind_master 来记录主从延迟的时间

在可靠策略下,需要等到旧的从节点完成所有的数据恢复(即seconds_behind_master为0)才成为主节点,提供写服务

image.png

在此期间只提供读服务、无法提供写服务,因此可靠策略会损失一定的可用性,取决于主从延迟的时间

在可用策略下会立即将从节点设置为新的主节点提供读写服务,某些场景下可能导致数据不一致

假设id自增,记录格式为(id,name),新增数据a,b,c

  1. 主节点已经新增(1,a),(2,b),(3,c)时宕机
  2. 从节点可能只重做数据(1,a),(2,b) 而(3,c)还在中继日志中
  3. 此时旧的从节点成为新的主节点又继续提供写服务,需要新增d,新增完d后才将中继日志的数据进行恢复

image.png

如果使用的binlog格式为statement或mixed,则会新增为(3,d)和(4,c)

image.png

如果格式为row,则会主键冲突报错,新增(3,d)后中继日志为(3,c)

image.png

在可用策略下可能导致数据不一致,使用row会提前暴露数据不一致的问题

基于GTID的主从切换

GTID 全局事务ID

格式为 server_uuid:gno

server_uuid 为节点标识

gno 为事务标识(事务提交时获得,全局自增)

在进行主从切换时,每个从节点同步数据的日志偏移量都不同,一般会找最新偏移量的从节点为新的主节点(这个偏移量是需要运维去定位的)

在GTID 全局事务ID出来后,binlog中每个事务有对应的GTID则可以通过GTID自动定位偏移量,不用手动定位

主从延迟

来源

默认情况下主从复制会使用异步复制,而在主从架构下一般会使用读写分离,主机服务写操作,从机服务读操作

由于使用异步复制,主从之间的数据一致性会存在一定的延迟,物理上主从会放在同一机房中,网络通信忽略不计,成本最大的就是从机SQL线程解析日志恢复数据的过程

如果恢复数据是一些大事务时会导致很长的延迟,比如在主机上执行批量操作耗时5s,在从机上执行时也会耗时那么久(资源大概一致)

可能写完操作就会进行读操作,如果此时从库还未重做数据就会导致写完查不到的数据不一致情况

先来看看哪些情况可能会导致主从延迟太长:

  1. 业务高峰期频繁读写(高TPS),从机不仅要同步数据,还要处理读操作
  2. 处理大事务,大事务导致延迟时间太久
  3. 从机硬件配置低,导致跟不上主机IO速度
  4. 主从机器可能参数不同(缓冲池、IO参数...)
  5. 从机本身就是延迟复制

...

当主从延迟过长时可以考虑使用方案缩短延迟:

  1. 调整redo log\bin log刷盘策略,增强IO
  2. canal监听(通知改为监听)
  3. 从机并行复制

从机并行复制借助于redo log、bin log两阶段提交时,redo log prepare阶段不会有锁冲突,可以并行执行

并行复制就是基于两阶段提交中的组提交,可以调整以下两个参数拉长组提交的时间,减慢主机写,加快从机重做数据

binlog_group_commit_sync_delay 延迟多少微秒后才调用 fsync

binlog_group_commit_sync_no_delay_count 累积多少次以后才调用 fsync

数据不一致解决方案

为了避免长时间的主从延迟,从机应该和主机有相同的参数、配置,并且要避免大事务

在业务高峰期还是可能存在主从延迟导致数据不一致,需要使用一些方案进行避免:

  1. 沟通业务:等待一段时间,比如用户修改完资料后进行审核状态

  2. 强一致性的读也走主库:这样就不存在主从延迟,使用方便,大量强一致性读操作就会导致主机压力大

  3. 等待从机没延迟(三种判断方式):

    • 比较 seconds_behind_master 是否为0,为0说明没延迟
    • 比较主从上的位点 Master_Log_File 和 Read_Master_Log_Pos(主库的最新位点)Relay_Master_Log_File 和 Exec_Master_Log_Pos(备库执行的最新位点)判断是否相同,相同则没延迟
    • 比较从机上GTID集合 Retrieved_Gtid_Set 和 Executed_Gtid_Set (备库收到的所有日志的 GTID 集合 和 备库所有已经执行完成的 GTID 集合)是否相同,相同则没延迟

    这个方案粒度大(实际上只需要判断事务是否重做,这里是一直判断是否有延迟),如果高峰期一直有延迟就会一直等待判断,不使用

  4. 修改主从复制方式为同步复制:数据强一致性,性能差

  5. 修改主从复制方式为半同步复制:一主一从下与同步复制相同,一主多从下查询不确定,需要判断该事务是否已重做

方案5需要做到细粒度的判断事务是否在从机上已经重做,有两种方式且实现较为复杂

判断偏移量

select master_pos_wait(file, pos,[timeout]) 用于判断当前偏移量是否已经超过该位置

file 为 binlog 文件,pos 为 偏移量,timeout为等待的时间

使用半同步复制时,一个从节点已经响应,其他从节点应该也是快要响应的状态,因此可以等待一段时间 50ms,100ms...

如果超时则可以在业务中再去查主机,要注意如果都超时就相当于又全打在主机上

通过该SQL能够以主库日志中偏移量的方式判断是否已执行该事务(已执行返回0):

  1. 写操作完成时顺便获取binlog文件和偏移量的信息
  2. 携带这两个参数加上超时时间使用该SQL判断是否已执行
  3. 如果返回0(已执行)则查从机,否则查主机(注意限流)

判断GTID

判断GTID的思路与上面相似

select wait_for_executed_gtid_set(gtid_set, [timeout])

SQL的作用是判断是否已经执行GTID集合 返回0,超时返回1

流程类似:

  1. 写操作时获取GTID集合
  2. 根据GTID集合判断从机是否已执行事务
  3. 已执行查询,否则查主库或限流

主从架构

由于binlog的数据复制,主从架构可以非常丰富,想怎么搭就怎么搭

一主一从:主负责写,从负责读,读写压力平分

一主多从:主负责写,从负责读,适合读多于写

双主热备:两个节点互为主从,读写压力平分,但存在循环同步的问题

当AB节点互为主从时,A收到写请求,要把bin log给B重做,B重做完(相当于写请求)又会把bin log给A重做,这样就会导致循环同步数据

在同步数据时携带节点的id(server id)解决循环同步问题

A收到写请求,binlog给B并携带自己的id,B重做完又把binlog给A,A发现binlog上server id是自己则不进行重做

总结

本篇文章以MySQL高可用为起点,聊到MySQL中的主从复制、切换、延迟、架构等

binlog的statement格式记录SQL,数据量小、传输快,但可能导致数据不一致

binlog的row格式记录修改数据,数据量大,传输慢,可以修复误操作数据

binlog的mixed混用statement、row的优点,在可用策略的主从切换还是会导致数据不一致

主从复制时主机dump线程监听binlog变更通知从机拉取,从机io线程将日志写入realy log中继日志,再由sql线程解析日志重做数据

同步复制需要所有从机响应,拥有强一致性,但性能最差

默认的异步复制性能最好,但可能延迟时会有数据一致性

半同步复制只需要一个从机响应,多从下性能好于同步复制,网络超时会使用异步复制

增强的半同步复制会在从机响应时才提交事务,相比于半同步复制一致性略好

延迟复制可以让从机延迟一段时间重做数据,误操作数据可以恢复

主从切换时只能满足CAP中其二,满足可靠会导致一段时间不可写,满足可用可能会出现数据不一致

把从机参数、配置调整为主机相同,避免使用大事务可以避免主从延迟太长

当主从延迟太长可以通过调整从机IO参数增强IO能力

发生主从延迟的数据一致性问题时:

  1. 沟通业务,能否使用审核等中间状态,等延迟过了再查看
  2. 强制走主机,注意压力可能太大
  3. 使用同步复制,性能差
  4. 使用半同步复制,一主多从下需要判断事务是否执行(偏移量/GTID),实现困难

常用的主从架构有:一主一从、一主多从、双主热备(通过server id解决循环同步问题)...

最后(不要白嫖,一键三连求求拉~)

本篇文章被收入专栏 MySQL进阶之路,感兴趣的同学可以持续关注喔

本篇文章笔记以及案例被收入 gitee-StudyJava、 github-StudyJava 感兴趣的同学可以stat下持续关注喔~

有什么问题可以在评论区交流,如果觉得菜菜写的不错,可以点赞、关注、收藏支持一下~

关注菜菜,分享更多干货,公众号:菜菜的后端私房菜

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/401766.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ABAQUS 软件在土木工程中的应用研究

摘要 随着土木工程的不断复杂化以及工程实践对土木工程分析计算要求越来越高,有限元技术在土木工程中的应用也越来越广泛。本文主要介绍国际大型通用有限元软件ABAQUS在土木工程中的应用,主要包括在建筑工程、桥梁工程、岩土工程中的应用,以期为相关工程…

【webrtc】m77 PacedSender

mediasoup是m77的代码,m77的代码并没有paced controller ,而且与paced sender 的逻辑混在了一起。结合大神们的代码分析,对照m77 进行 理解。m77 有ProbeController。给pacersender 更新飞行数据:PacedSender::InsertPacket(size_t bytes) 对应的是 PacingController::OnPa…

2023年12月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 下面代码的输出结果是?( ) dict1 = {1: 10, 2: 20, 3: 30} dict2 <

XML的写法

下面我将以如下代码来解释下XML的写法 <?xml version"1.0" encoding"UTF-8" ?> <Steam><steam id"1"><zhanghao>admin</zhanghao><mima>123</mima><num>120</num></steam><st…

学习数仓工具 dbt

DBT 是一个有趣的工具&#xff0c;它通过一种结构化的方式定义了数仓中各种表、视图的构建和填充方式。 dbt 面相的对象是数据开发团队&#xff0c;提供了如下几个最有价值的能力&#xff1a; 支持多种数据库通过 select 来定义数据&#xff0c;无需编写 DML构建数据时&#…

色彩搭配:打造视觉吸引力与用户体验的关键

title: 色彩搭配&#xff1a;打造视觉吸引力与用户体验的关键 date: 2024/2/22 12:01:11 updated: 2024/2/22 12:01:11 tags: 网站色彩搭配视觉吸引力品牌形象用户体验设计色彩心理学配色技巧色轮互补 在当今数字化时代&#xff0c;网站已经成为了人们获取信息、进行交流和进行…

嵌入式学习之Linux入门篇——使用VMware创建Unbuntu虚拟机

目录 主机硬件要求 VMware 安装 安装Unbuntu 18.04.6 LTS 新建虚拟机 进入Unbuntu安装环节 主机硬件要求 内存最少16G 硬盘最好分出一个单独的盘&#xff0c;而且最少预留200G&#xff0c;可以使用移动固态操作系统win7/10/11 VMware 安装 版本&#xff1a;VMware Works…

Jmeter内置变量 vars 和props的使用详解

JMeter是一个功能强大的负载测试工具&#xff0c;它提供了许多有用的内置变量来支持测试过程。其中最常用的变量是 vars 和 props。 vars 变量 vars 变量是线程本地变量&#xff0c;它们只能在同一线程组内的所有线程中使用&#xff08;线程组内不同线程之间变量不共享&#…

机器学习——正规方程

正规方程的基本介绍 之前我们使用梯度下降算法求代价函数J(θ)的最小值&#xff0c;而梯度下降算法是通过一步步不断地迭代来收敛到全局最小值&#xff0c;如下 而正规方程则是另一种求解J(θ)最小值的方法&#xff0c;并且正规方程不需要通过迭代&#xff0c;而是一次性得到θ…

体育网站的比分、赛事数据一般从哪里获取?

像一般的体育类门户网站&#xff0c;或者是APP产品&#xff0c;换句话说&#xff0c;不是专业做数据的公司&#xff0c;基本上都是购买付费的api接口&#xff0c;越是大公司越是依靠从大的服务商处购买的。比如说whoscored这样的网站&#xff0c;以及像曼城、利物浦这样的俱乐部…

跨境电商本土化运营:深度融合本地市场,提升用户体验与市场份额

随着全球经济的不断发展&#xff0c;跨境电商在国际贸易中扮演着越来越重要的角色。然而&#xff0c;单一地面对全球市场可能并不足以满足用户的多样化需求&#xff0c;因此&#xff0c;跨境电商需要与本地市场深度融合&#xff0c;实现本土化运营。本文Nox聚星将和大家探讨跨境…

软件兼容性测试要考虑什么?

1、向前兼容和向后兼容。向前兼容是指可以使用软件的未来版本&#xff0c;向后兼容是指可以使用软件的以前版本。并非所有的软件都要求向前兼容和向后兼容&#xff0c;这是软件设计者需要决定的产品特性。 2、不同版本之间的兼容。不同版本之间的兼容指要实现测试平台和应用软…

【elasticsearch实战】知识库文件系统检索工具FSCrawler

需求背景 最近有一个需求需要建设一个知识库文档检索系统&#xff0c;这些知识库物料附件的文档居多&#xff0c;有较多文档格式如&#xff1a;PDF, Open Office, MS Office等&#xff0c;需要将这些格式的文件转化成文本格式&#xff0c;写入elasticsearch 的全文检索索引&am…

解决app中以webview的方式嵌入h5网页,h5网页加载不出来

问题描述&#xff1a;我的h5网页在web端和手机浏览器都能正常渲染展示&#xff0c;但是嵌入到客户的webview中&#xff0c;渲染加载不出来&#xff0c;仔细检查代码之后并没有任何代码错误和后台报错。抓耳挠腮查找两天之后发现&#xff0c;原因为整个h5网页的最外层高度设置成…

六、回归与聚类算法 - 线性回归

目录 1、线性回归的原理 1.1 应用场景 1.2 什么是线性回归 1.2.1 定义 1.2.2 线性回归的特征与目标的关系分析 2、线性回归的损失和优化原理 2.1 损失函数 2.2 优化算法 2.2.1 正规方程 2.2.2 梯度下降 3、线性回归API 4、回归性能评估 5、波士顿房价预测 5.1 流…

打造纯Lua组件化开发模式:Unity xLua框架详解

在传统的Unity开发中&#xff0c;通常会使用C#来编写游戏逻辑和组件。但是&#xff0c;随着Lua在游戏开发中的应用越来越广泛&#xff0c;我们可以将游戏逻辑和组件完全用Lua来实现&#xff0c;实现纯Lua的组件化开发模式。这样做的好处是可以更加灵活地修改游戏逻辑&#xff0…

Python: argparse基本用法

Python: argparse基本用法 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;【Matplotlib之旅&#xff1a;零基础精通数据可视化】 &#x1f4a1; 创作高质量博文&#xff0c;分享更多关于深度学习、PyTorch、Python领域的优质内容&#xff0…

小程序--引入vant组件库

一、npm初始化 在微信开发者工具中打开终端&#xff0c;输入npm init&#xff0c;对npm进行初始化 二、安装vant组件库 npm install vant/weapp 三、修改app.json 修改 app.json&#xff0c;移除全局配置 "style": "v2"&#xff0c;否则 Vant 组件的样式…

Vectorlabs橙黄网胞盘菌凝集素(Aleuria Aurantia Lectin)

与荆豆凝集素和莲藕凝集素偏好&#xff08;α-1,2&#xff09;连接的岩藻糖残基不同&#xff0c;AAL由2个相同36kDa大小的亚基组成的二聚体&#xff0c;与fucose linked (α -1,6) to N-acetylglucosamine或fucose linked (α -1,3) to N-acetyllactosamine相关结构结合。AAL也…

Linux多线程服务端编程:使用muduo C++网络库 学习笔记 第十二章 C++经验谈(二)

12.8.4 用partition()实现“重排数组&#xff0c;让奇数位于偶数前面” std::partition()的作用是把符合条件的元素放到区间首部&#xff0c;不符合条件的元素放到区间后部&#xff0c;我们只需把“符合条件”定义为“元素是奇数”就能解决这道题。复杂度是O(N)时间和O(1)空间…