三高Mysql - 搭建“三高”架构之复制(下)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
日志服务 SLS,月写入数据量 50GB 1个月
简介: 三高Mysql - 搭建“三高”架构之复制(下)

GTID增强复制模式


经过上一个小节的介绍,我们发现传统主备节点复制的操作比较麻烦,特别是LOG_FILE + LOG_POS 的方式处理比较麻烦,根本原因是备库不知道从哪一个log开始进行复制,Mysql针对这一点在更高的版本中提供了全局事务的特性,给每一个事务配置一个唯一ID,也就是Mysql5.6的GTID增强模式,GTID就是 server_uuid:gno 组成一个键值对:

  • server_uuid(节点的UUID)
  • Gno:事务流水号(回滚之后进行回收)

启动GTID模式的配置很简单,在配置文件中加入如下的配置:

  • gitd_mode = on
  • enforece_gtid_consistency = on

最后使用GTID配置可以修改上一节最后部分提到的change..master部分:


change master to 
MASTER_HOST = 'xx.xx.xx.xx'
MASTER_USER = 'root'
master_auto_position = 1


GTID复制是为了增强主从复制减少故障率而出现的,推荐默认开启


binlog格式格式演变


注意在主从复制中最为关键的binlog格式随着Mysql的升级是做过调整的,在Mysql5.0之前的binlog格式是statement格式,同时内部记录的是原文,而对于一些特殊的语句来说同样的语句可能会有不同的效果,这时候就会有数据风险,比如下面的语句在处理对过程中会出现问题:


网络异常,图片无法展示
|


为什么要使用row格式


通过上面的介绍,我们大致了解了为什么需要使用row格式,因为row格式不记录SQL语句的原文,而是记录数据行的变化。但是row格式依然没有摆脱记录逻辑日志的这一条规则,而记录文本数据数据量比statement更大,之后会出现空间占用比较大的问题 。

进一步改进:mixed格式的binlog

针对binlog的row格式文本存储的问题,Mysql在提供了一种混合row和statement的对混合模式,对于有数据同步风险的使用row格式,而对于没有风险的则直接使用原文。

另外statement和row格式也称为给予语句的复制和给予行的复制,只是说法上的差别而已本质上并没有差别。


主备延迟如何处理


首先我们需要了解为什么主备之间存在延迟?

  • log的传送其实开销比较小,主要的消耗是消费relay log的耗时,
  • 备库的性能比主库要小很多
  • 备库承担了很多分析SQL的任务,压力比主库要打
  • 如果主库有长事务没有提交。

通常主备延迟有下面的解决方式:

  • 主备之间使用相同配置的机器
  • 备库关闭log实时落盘
  • 使用大数据系统分担日志处理任务

但是上面的处理也不是完美的,存在比较大的缺陷,并且通过上面的处理方式之后,依然没有办法完全排除所有的问题,还有诸如备库的性能由于被动接受复制,性能要比主库大打折扣,主库支持“多线程”而备库限制于“单线程”。

总结上面的内容可以发现主备延迟的特点如下:

  • 备库延迟主要是备库执行总是要比主库要慢。
  • 通过升级备库的硬件和关闭log实时落盘提高性能
  • 增加其他的组件分担复制的压力
  • 对于新时代的应用系统,使用“组复制”是官方的推荐选择。

针对上面的问题,Mysql对于传统的复制模式提供了更加细分的解决方式:并行复制。并行复制通常有两种思路,第一种是按表分发,第二种是按行分发,以及较新版本出现的事务组并行策略。

并行复制的原理

注意:Mysql 5.6的版本才出现并行复制。

并行复制是在主从复制同步的时候,从库在获取到主库的binlog日志并且保存为relay log之后,把重放relay log的任务另外分配一个叫做 worker的线程执行,sql线程则执行分配relay log的任务,从库只需要读取并分配任务不需要自己进行处理,从而更高效的重放relay log。

难点:如何分配relay log日志

这里还涉及几个关联问题:事务存在上下文依赖如何处理?如果存在冲突如何分配处理?(比如新增数据同时并行删除)。

并行复制名称看起来比较高大上,但是最大的问题是仅仅只是加快了重访relay log的速度,对于binlog 解析为relay log没有进行更多改进,也就是说把任务分担给了第三者让自己压力小了一点点,但是自己的处理速度和之前基本没太大变化。我们可以通过下面的图进行了解:


网络异常,图片无法展示
|


并行复制 - 分配思路:

因为并行复制的难点在于如何分发relay log,mysql提供了两种分配方式:按行分配按表分配

在最早期还有一种思路出现那就是按库并行的策略:这种处理方式是分发选择方式特别快,同时支持各种的log格式分发,但是同时缺点也非常明显,库粒度非常大并且负载均衡非常难。

开启方式:

salve-parallel-type=DATABASE,这是最初配置,由按照库的方式并行复制,这样的处理方式有下面的特点:

  • 分发选择非常快,支持各种log格式
  • 难以进行负载均衡,库粒度非常大。因为所有的worker实际上都是分配到一个单独的库进行处理,和之前的单线程处理方式并没有太大的却别。
    基于上面的一些问题,在后续的版本中Mysql对于并行复制进行了优化。

当然Mysql不会满足于库的粒度,所以后续基于按库复制基础上出现更多分配的方式:

按行分配:由于binlog记录的是数据行的改动内容,如果修改的不是同一行就可以分配,否则就把他们分配到同一个线程执行。

按表分配:语句按照不同的表进行分类,同一个表的事务放到同一个线程进行分配。

按事务组分配:Mysql5.7提出,使用事务组的方式进行并发提交和处理,下文将会单独介绍。


Mysql按照事务组并行策略(Mysql5.7新特性)

在介绍具体的策略之前,需要解释一下主库对于binlog刷盘的原理,binlog 刷盘分为两步动作,通过这两步动作之后,由此主库的binlog多线程访问,对于多线程事务的提交就可以进行并行刷盘的操作:

  1. binlog → binlog cache 写到binlog内存文件
  2. binlog内存文件刷到磁盘中(fsync 持久化磁盘)

事务组并行策略:


下面这图看起来十分复杂,其实简单理解可以认为每一次同步类似我们一次ctrl+s的动作,我们每一次的保存动作都需要刷新到磁盘,在多线程的操作过程中修改先是修改内存,然后按照顺序的进行刷盘。这里有读者可能会疑问,如果线程之间存在事务交叉怎么办?所以这里会依据binlog刷磁盘的逻辑,按照类似按行分配的处理方式将多线程写入到一个binlog缓冲文件之后一次刷新磁盘。

这样事务组并行缓冲合并刷新到方式,使得并行分配肯定会存在下面两种原则:

  • 能够在同一个组里提交的事务,一定不会修改同一行
  • 主库上可以并行执行的事务,备库上也一定是可以并行执行的

吐槽:其实这个特性说白了还是“抄”了Mysql原作者的思路,这里提一嘴MariaDB 是在 MySQL 版权被 Oracle 收购后,由 MySQL 创始人 Monty 创立的一个开源数据库,其版权授予了“MariaDB基金会(非营利性组织)。果然最了解儿子的还是亲爹。

下面的结构图是按照上面的文字描述的事物组并行策略的改进图:


网络异常,图片无法展示
|


可以看到上面的处理方式十分耗费IO性能,并行刷盘频繁浪费性能,可以发现最后一步可以合并前面的并行修改通过一次刷盘完成,所以出现了下面的优化方式:


网络异常,图片无法展示
|


事务组的含义就是将下面多个并行刷盘的操作合并为同一个,但是这时候又会有一个疑问到底等待多久合并并且刷新一次磁盘?

Mysql 使用了下面的参数进行控制:


(两个条件是或的关系)

  • binlog_group_commit_sync_delay:延迟多少微秒之后调用fsync()
  • binlog_group_commit_sync_no_dalay_count:类似多少次之后才调用fsync()

网络异常,图片无法展示
|


事务组并行策略优化(Mysql5.7.22版本)

在5.7版本中还存在过一个小版本的升级对于这个策略做了更多的扩展,比如下面的参数:

binlog-transaction-dependency-tracking 参数

  • COMMIT_ORDER:默认策略
  • WRITESET:没有修改相同行的事务可以并行。
  • WRITESET_SESSION:同一个线程先后执行两个事务不能并行。


强制走主库


如何判断备库已经追上去:

  • 强制延时
  • seconds_behind_master = 0
  • 对比binlog执行位点
  • 对比GTID对比情况

但是无法从根本上解决备库延迟的问题,它具备下面几个无法解决的根本性问题:

  • binlog 传送和redo log 重放需要时间,这时候受到网络IO或者磁盘IO阻塞的影响
  • 备库复制永远只能尽可能减小,无法从本质上完美解决延迟问题。
  • 备库因需要

针对次依然可以使用下面的方式判断具体事务是否重放:

  • 等待binlog位点:比如通过下面的命令直接监听到具体位置的变动,一旦有变动就认为主库的数据事务完成了。


网络异常,图片无法展示
|


  • 等待GTID(5.7.6之后每次都会返回GTID),通过下面的命令检查唯一事务ID:


网络异常,图片无法展示
|


简单-双主架构


主-主复制架构一半在一些项目比较小或者一些小公司经常使用,主主复制也就是两个库不存在主备关系,而是通过一个热备的库对于主节点宕机之后临时支撑业务使用。简单理解可以理解为柴油发电机,在停电的时候临时充当使用。

  • 两个节点均为Master
  • 两个节点均为Salve
  • 两库的数据互相复制
  • 如果其中一个出现问题,立刻切换到另一个库。


主主架构有下面一些比较明显的问题:

  • 数据冲突
  • 两边同时插入数据,出现冲突
  • 约定好插入不同ID
  • 只有一些库可写,另一个只读
  • 切换过快的数据库丢失问题。
  • 应用切换问题
  • 应用自己切换比较麻烦
  • keepalived 手段自动切换
  • 循环复制问题
  • 理论上的问题。
  • 未开GTID:使用ServerID过滤。


小结


在复制的部分介绍了复制的基本原理以及Mysql复制的三种方式,在5.6之后还提供了GTID的复制模式使得复制的故障率进一步下降,而针对复制的核心一方面是binlog文件,这里简单的介绍了binlog文件的三种写入格式,最早的statement,常用的row和一种推荐的混合模式,然而混合模式使用频率依然不如row多,内部的机制在实践过程中依然发现不少问题。

而另一方面则是在整个复制过程中插入“中间层”加快部分操作的处理速度,比如在重放relay log中加入一个worker专门负责处理和分发重放relay log的任务,Mysql在这个relay log重放分发的过程中做文章引入了并行复制,并行复制在早期使用按库的力度分配,这虽然很简单好实现但是因为粒度太大被立马改进,后续出现了按行分配和按表分配,最终出现了按事务组的策略分配,这些内容我们只需要理解,并不要去背诵或则牢记。

介绍完主备复制以及相关优化之后,我们切换视角来到了主库这边,主库这边也出现了更优秀的同步策略,那就是直接针对点进行监控,当然这种处理方式比较极端多数情况下不会接触到所以本部分没有过多介绍。

最后我们简单介绍了一下双主的架构,适合大部分的中小公司,对于个人开发的开源项目也能基本应付需求。


写在最后


复制部分仅仅是三高Mysql的第一个大关,后面和还有切换和扩展等着我们介绍,这里也会继续整理给大家带来更多好内容。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
11天前
|
存储 SQL 关系型数据库
MySQL进阶突击系列(03) MySQL架构原理solo九魂17环连问 | 给大厂面试官的一封信
本文介绍了MySQL架构原理、存储引擎和索引的相关知识点,涵盖查询和更新SQL的执行过程、MySQL各组件的作用、存储引擎的类型及特性、索引的建立和使用原则,以及二叉树、平衡二叉树和B树的区别。通过这些内容,帮助读者深入了解MySQL的工作机制,提高数据库管理和优化能力。
|
1月前
|
存储 SQL 关系型数据库
Mysql高可用架构方案
本文阐述了Mysql高可用架构方案,介绍了 主从模式,MHA模式,MMM模式,MGR模式 方案的实现方式,没有哪个方案是完美的,开发人员在选择何种方案应用到项目中也没有标准答案,合适的才是最好的。
164 3
Mysql高可用架构方案
|
1月前
|
SQL 存储 缓存
【赵渝强老师】MySQL的体系架构
本文介绍了MySQL的体系架构,包括Server层的7个主要组件(Connectors、Connection Pool、Management Service & Utilities、SQL Interface、Parser、Optimizer、Query Caches & Buffers)及其作用,以及存储引擎层的支持情况,重点介绍了InnoDB存储引擎。文中还提供了相关图片和视频讲解。
【赵渝强老师】MySQL的体系架构
|
24天前
|
SQL 存储 关系型数据库
MySQL进阶突击系列(01)一条简单SQL搞懂MySQL架构原理 | 含实用命令参数集
本文从MySQL的架构原理出发,详细介绍其SQL查询的全过程,涵盖客户端发起SQL查询、服务端SQL接口、解析器、优化器、存储引擎及日志数据等内容。同时提供了MySQL常用的管理命令参数集,帮助读者深入了解MySQL的技术细节和优化方法。
|
22天前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
1月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
43 3
|
1月前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
21天前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
142 68
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
23天前
|
设计模式 负载均衡 监控
探索微服务架构下的API网关设计
在微服务的大潮中,API网关如同一座桥梁,连接着服务的提供者与消费者。本文将深入探讨API网关的核心功能、设计原则及实现策略,旨在为读者揭示如何构建一个高效、可靠的API网关。通过分析API网关在微服务架构中的作用和挑战,我们将了解到,一个优秀的API网关不仅要处理服务路由、负载均衡、认证授权等基础问题,还需考虑如何提升系统的可扩展性、安全性和可维护性。文章最后将提供实用的代码示例,帮助读者更好地理解和应用API网关的设计概念。
54 8
|
1月前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
54 1
服务架构的演进:从单体到微服务的探索之旅

热门文章

最新文章