mysql-集群概述

article/2025/11/10 10:37:34

mysql-主从模式

mysql-集群概述

  • 可用性设计
    站点高可用,冗余站点服务高可用,冗余服务
    数据高可用,冗余数据
    保证高可用的方法是冗余。但是数据冗余带来的问题是数据一致性问题

  • 实现高可用的方案有以下几种架构模式:
    主从模式
    简单灵活,能满足多种需求。比较主流的用法,但是写操作高可用需要自行处理。
    双主模式
    互为主从,有双主双写、双主单写两种方式,建议使用双主单写

  • 扩展性设计
    扩展性主要围绕着读操作扩展和写操作扩展展开。
    如何扩展以提高读性能

  • 加从库
    简单易操作,方案成熟。
    从库过多会引发主库性能损耗。建议不要作为长期的扩充方案,应该设法用良好的设计避免
    持续加从库来缓解读性能问题。

  • 分库分表
    可以分为垂直拆分和水平拆分,垂直拆分可以缓解部分压力,水平拆分理论上可以无限扩
    展。

  • 如何扩展以提高写性能
    分库分表

  • 一致性设计
    一致性主要考虑集群中各数据库数据同步以及同步延迟问题。可以采用的方案如下:
    不使用从库
    扩展读性能问题需要单独考虑,否则容易出现系统瓶颈。
    增加访问路由层
    可以先得到主从同步最长时间t,在数据发生修改后的t时间内,先访问主库

主从模式

适用场景
MySQL主从模式是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,从节点可以复制主数据库中的所有数据库,或者特定的数据库,或者特定的表
在这里插入图片描述

  • mysql主从复制用途:
    实时灾备,用于故障切换(高可用)
    读写分离,提供查询服务(读扩展)
    数据备份,避免影响业务(高可用)
  • 主从部署必要条件:
    从库服务器能连通主库
    主库开启binlog日志(设置log-bin参数)
    主从server-id不同
    在这里插入图片描述
    修改my.ini,my.cnf
#log-bin=ON
#log-bin-basename=mysqlbinlog
binlog-format=ROW
log-bin=mysqlbinlog

主从-实现原理

在这里插入图片描述
主从复制整体分为以下三个步骤:

  1. 主库将数据库的变更操作记录到Binlog日志文件中
  2. 从库读取主库中的Binlog日志文件信息写入到从库的Relay Log中继日志中
  3. 从库读取中继日志信息在从库中进行Replay,更新从库数据信息
    在上述三个过程中,涉及了Master的BinlogDump Thread和Slave的I/O Thread、SQL Thread,它们的作用如下
  • Master服务器对数据库更改操作记录在Binlog中,BinlogDump Thread接到写入请求后,读取Binlog信息推送给Slave的I/O Thread。
  • Slave的I/O Thread将读取到的Binlog信息写入到本地Relay Log中。
  • Slave的SQL Thread检测到Relay Log的变更请求,解析relay log中内容在从库上执行。
    上述过程都是异步操作,俗称异步复制,存在数据延迟现象

在这里插入图片描述
mysql主从复制存在的问题:
主库宕机后,数据可能丢失
从库只有一个SQL Thread,主库写压力大,复制很可能延时
解决方法:
半同步复制—解决数据丢失的问题
并行复制----解决从库复制延迟的问题

半同步复制

为了提升数据安全,MySQL让Master在某一个时间点等待Slave节点的 ACK(Acknowledgecharacter)消息,接收到ACK消息后才进行事务提交,这也是半同步复制的基础,MySQL从5.5版本开始引入了半同步复制机制来降低数据丢失的概率。介绍半同步复制之前先快速过一下 MySQL 事务写入碰到主从复制时的完整过程,主库事务写入分为 4个步骤
InnoDB Redo File Write (Prepare Write)
Binlog File Flush & Sync to Binlog File
InnoDB Redo File Commit(Commit Write)
Send Binlog to Slave

  • 当Master不需要关注Slave是否接受到Binlog Event时,即为传统的主从复制。
  • 当Master需要在第三步等待Slave返回ACK时,即为 after-commit,半同步复制(MySQL 5.5引入)。
  • 当Master需要在第二步等待 Slave 返回 ACK 时,即为 after-sync,增强半同步(MySQL 5.7引入)。
    下图是 MySQL 官方对于半同步复制的时序图,主库等待从库写入 relay log 并返回 ACK 后才进行Engine Commit。
    在这里插入图片描述

并行复制

MySQL的主从复制延迟一直是受开发者最为关注的问题之一,MySQL从5.6版本开始追加了并行复制功能,目的就是为了改善复制延迟问题,并行复制称为enhanced multi-threaded slave(简称MTS)。在从库中有两个线程IO Thread和SQL Thread,都是单线程模式工作,因此有了延迟问题,我们可以采用多线程机制来加强,减少从库复制延迟。(IO Thread多线程意义不大,主要指的是SQL Thread多线程)在MySQL的5.6、5.7、8.0版本上,都是基于上述SQL Thread多线程思想,不断优化,减少复制延迟。

MySQL 5.6并行复制原理

MySQL 5.6版本也支持所谓的并行复制,但是其并行只是基于库的。如果用户的MySQL数据库中是多个
库,对于从库复制的速度的确可以有比较大的帮助
MySQL的主从复制延迟一直是受开发者最为关注的问题之一,MySQL从5.6版本开始追加了并行复制功
能,目的就是为了改善复制延迟问题,并行复制称为enhanced multi-threaded slave(简称MTS)。
在从库中有两个线程IO Thread和SQL Thread,都是单线程模式工作,因此有了延迟问题,我们可以采
用多线程机制来加强,减少从库复制延迟。(IO Thread多线程意义不大,主要指的是SQL Thread多线
程)
在MySQL的5.6、5.7、8.0版本上,都是基于上述SQL Thread多线程思想,不断优化,减少复制延迟

MySQL 5.6并行复制原理

MySQL 5.6版本也支持所谓的并行复制,但是其并行只是基于库的。如果用户的MySQL数据库中是多个
库,对于从库复制的速度的确可以有比较大的帮助
在这里插入图片描述
基于库的并行复制,实现相对简单,使用也相对简单些。基于库的并行复制遇到单库多表使用场景就发挥不出优势了,另外对事务并行处理的执行顺序也是个大问题。

  • MySQL 5.7并行复制原理
    MySQL 5.7是基于组提交的并行复制,MySQL 5.7才可称为真正的并行复制,这其中最为主要的原因就
    是slave服务器的回放与master服务器是一致的,即master服务器上是怎么并行执行的slave上就怎样进
    行并行回放。不再有库的并行复制限制。
  • MySQL 5.7中组提交的并行复制究竟是如何实现的?
    MySQL 5.7是通过对事务进行分组,当事务提交时,它们将在单个操作中写入到二进制日志中。如果多
    个事务能同时提交成功,那么它们意味着没有冲突,因此可以在Slave上并行执行,所以通过在主库上
    的二进制日志中添加组提交信息。
    MySQL 5.7的并行复制基于一个前提,即所有已经处于prepare阶段的事务,都是可以并行提交的。这
    些当然也可以在从库中并行提交,因为处理这个阶段的事务都是没有冲突的。在一个组里提交的事务,
    一定不会修改同一行。这是一种新的并行复制思路,完全摆脱了原来一直致力于为了防止冲突而做的分
    发算法,等待策略等复杂的而又效率底下的工作。
    InnoDB事务提交采用的是两阶段提交模式。一个阶段是prepare,另一个是commit。
    为了兼容MySQL 5.6基于库的并行复制,5.7引入了新的变量slave-parallel-type,其可以配置的值有:
    https://dev.mysql.com/doc/refman/5.7/en/replication-options-replica.html
    在这里插入图片描述

DATABASE(默认值,基于库的并行复制方式)、LOGICAL_CLOCK(基于组提交的并行复制方式)。

那么如何知道事务是否在同一组中,生成的Binlog内容如何告诉Slave哪些事务是可以并行复制的?
在MySQL 5.7版本中,其设计方式是将组提交的信息存放在GTID中。为了避免用户没有开启GTID功能
(gtid_mode=OFF),MySQL 5.7又引入了称之为Anonymous_Gtid的二进制日志event类型
ANONYMOUS_GTID_LOG_EVENT。
通过mysqlbinlog工具分析binlog日志,就可以发现组提交的内部信息

在这里插入图片描述
MySQL 5.7二进制日志较之原来的二进制日志内容多了last_committed和
sequence_number,last_committed表示事务提交的时候,上次事务提交的编号,如果事务具有相同
的last_committed,表示这些事务都在一组内,可以进行并行的回放。

MySQL8.0 并行复制

MySQL8.0 是基于write-set的并行复制。MySQL会有一个集合变量来存储事务修改的记录信息(主键哈
希值),所有已经提交的事务所修改的主键值经过hash后都会与那个变量的集合进行对比,来判断改行
是否与其冲突,并以此来确定依赖关系,没有冲突即可并行。这样的粒度,就到了 row级别了,此时并
行的粒度更加精细,并行的速度会更快

  • 并行复制配置与调优
    binlog_transaction_dependency_history_size
    用于控制集合变量的大小

  • binlog_transaction_depandency_tracking
    用于控制binlog文件中事务之间的依赖关系,即last_committed值。
    COMMIT_ORDERE: 基于组提交机制
    WRITESET: 基于写集合机制
    WRITESET_SESSION: 基于写集合,比writeset多了一个约束,同一个session中的事务
    last_committed按先后顺序递增

  • transaction_write_set_extraction
    用于控制事务的检测算法,参数值为:OFF、 XXHASH64、MURMUR32

  • master_info_repository
    开启MTS功能后,务必将参数master_info_repostitory设置为TABLE,这样性能可以有50%~80%
    的提升。这是因为并行复制开启后对于元master.info这个文件的更新将会大幅提升,资源的竞争
    也会变大

  • slave_parallel_workers
    若将slave_parallel_workers设置为0,则MySQL 5.7退化为原单线程复制,但将
    slave_parallel_workers设置为1,则SQL线程功能转化为coordinator线程,但是只有1个worker
    线程进行回放,也是单线程复制。然而,这两种性能却又有一些的区别,因为多了一次
    coordinator线程的转发,因此slave_parallel_workers=1的性能反而比0还要差

  • slave_preserve_commit_order
    MySQL 5.7后的MTS可以实现更小粒度的并行复制,但需要将slave_parallel_type设置为
    LOGICAL_CLOCK,但仅仅设置为LOGICAL_CLOCK也会存在问题,因为此时在slave上应用事务的
    顺序是无序的,和relay log中记录的事务顺序不一样,这样数据一致性是无法保证的,为了保证事
    务是按照relay log中记录的顺序来回放,就需要开启参数slave_preserve_commit_order

  • 要开启enhanced multi-threaded slave其实很简单,只需根据如下设置

#log-bin=ON
#log-bin-basename=mysqlbinlog
binlog-format=ROW
log-bin=mysqlbinlogslave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=16
slave_pending_jobs_size_max = 2147483648
slave_preserve_commit_order=1
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log_recovery=ON

并行复制监控

在使用了MTS后,复制的监控依旧可以通过SHOW SLAVE STATUS\G,但是MySQL 5.7在performance_schema库中提供了很多元数据表,可以更详细的监控并行复制过程

show tables like 'replication%';

在这里插入图片描述
通过replication_applier_status_by_worker可以看到worker进程的工作情况:
在这里插入图片描述

最后,如果MySQL 5.7要使用MTS功能,建议使用新版本,最少升级到5.7.19版本,修复了很多Bug

读写分离

读写分离引入时机

大多数互联网业务中,往往读多写少,这时候数据库的读会首先成为数据库的瓶颈。如果我们已经优化了SQL,但是读依旧还是瓶颈时,这时就可以选择“读写分离”架构了。读写分离首先需要将数据库分为主从库,一个主库用于写数据,多个从库完成读数据的操作,主从库之间通过主从复制机制进行数据的同步,如图所示。
在这里插入图片描述

在应用中可以在从库追加多个索引来优化查询,主库这些索引可以不加,用于提升写效率。
读写分离架构也能够消除读写锁冲突从而提升数据库的读写性能。使用读写分离架构需要注意:主从同步延迟和读写分配机制问题

主从同步延迟

使用读写分离架构时,数据库主从同步具有延迟性,数据一致性会有影响,对于一些实时性要求比较高的操作,可以采用以下解决方案

  • 写后立刻读
    在写入数据库后,某个时间段内读操作就去主库,之后读操作访问从库。
  • 二次查询
    先去从库读取数据,找不到时就去主库进行数据读取。该操作容易将读压力返还给主库,为了避免恶意攻击,建议对数据库访问API操作进行封装,有利于安全和低耦合。
  • 根据业务特殊处理
    根据业务特点和重要程度进行调整,比如重要的,实时性要求高的业务数据读写可以放在主库。对于次要的业务,实时性要求不高可以进行读写分离,查询时去从库查询。
读写分离落地

读写路由分配机制是实现读写分离架构最关键的一个环节,就是控制何时去主库写,何时去从库读。目
前较为常见的实现方案分为以下两种

  • 基于编程和配置实现(应用端)

程序员在代码中封装数据库的操作,代码中可以根据操作类型进行路由分配,增删改时操作主库,
查询时操作从库。这类方法也是目前生产环境下应用最广泛的。优点是实现简单,因为程序在代码
中实现,不需要增加额外的硬件开支,缺点是需要开发人员来实现,运维人员无从下手,如果其中
一个数据库宕机了,就需要修改配置重启项目

  • 基于服务器端代理实现(服务器端)

在这里插入图片描述
间件代理一般介于应用服务器和数据库服务器之间,从图中可以看到,应用服务器并不直接进入
到master数据库或者slave数据库,而是进入MySQL proxy代理服务器。代理服务器接收到应用服
务器的请求后,先进行判断然后转发到后端master和slave数据库

目前有很多性能不错的数据库中间件,常用的有MySQL Proxy、MyCat以及Shardingsphere等等

  • MySQL Proxy:是官方提供的MySQL中间件产品可以实现负载平衡、读写分离等。
  • MyCat:MyCat是一款基于阿里开源产品Cobar而研发的,基于 Java 语言编写的开源数据库中间
    件。
  • ShardingSphere:ShardingSphere是一套开源的分布式数据库中间件解决方案,它由ShardingJDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。已经在2020年4月16日从Apache孵化器毕业,成为Apache顶级项目。
  • Atlas:Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个数据库中间件。
  • Amoeba:变形虫,该开源框架于2008年开始发布一款 Amoeba for MySQL软件

http://chatgpt.dhexx.cn/article/QKrBUa5k.shtml

相关文章

MySQL数据库集群的原理与搭建

【1.应用背景】 在最近做的项目中,因为有一个短时间内很多人访问服务,会频繁访问数据库,看到这里不免有些人会想起数据库集群。我们组长也想到了用数据库集群,于是就带着我们几个研究起来了mysql数据库集群的搭建。因为我们几个的…

MySQL 数据库主从集群搭建

文章目录 1 准备工作2 配置主数据库3 配置从库4 从库设置只读用户5 推荐参考资料 1 准备工作 1 选择一个服务器当做主服务器,将服务器上需要的数据进行备份 2 安装从库的 MySQL,需要与主服务器的版本保持一致 3 将主服务器上的数据同步到从库中(主从集…

MySQL数据库主从集群架构搭建

一、相关概念 二、配置一主一从 三、配置一主多从 四、配置主从从 五、配置主主结构 六、配置半同步复制模式 一、相关概念 1.1 主从同步介绍: 存储数据的服务结构,分为2种角色: 主服务器(master):接受客户端访问连接 从服务器(sl…

谈谈mysql数据库集群

现在,随着上网人数的激增,一些大型的网站开始使用数据库集群来提高数据库的可靠性和数据库的性能。那么在介绍数据库集群之前首先需要弄清楚几个问题。 1.为什么要用数据库集群 (1)通过使用数据库集群可以使读写分离,提…

MySQL集群配置

1. MySQL集群简介 MySQL Cluster 是MySQL适合于分布式计算环境的高实用、高冗余版本。它采用了NDB Cluster 存储引擎,允许在1个 Cluster 中运行多个MySQL服务器。MySQL Cluster 是一种技术,该技术允许在无共享的系统中部署“内存中”数据库的 Cluster 。…

MySQL数据库集群(双主双从)

文章目录 MySQL数据库集群(双主双从)实验环境双主双从双主双从进行测试 MySQL数据库集群(双主双从) 实验环境 保证每台centos7服务器配置静态的IP,初始化服务器,关闭防火前和selinux,保证四台服务器之间可以互相通信,并且做好hosts域名解析…

数据库与集群

数据库与集群 1、数据库集群 概念:数据库集群,顾名思义,就是利用至少两台或者多台数据库服务器,构成一个虚拟单一数据库逻辑映像,像单数据库系统那样,向客户端提供透明的数据服务。 数据库集群两个关键定…

数据库-mysql集群方案总结

一 概念解读 1 数据库高可用 高可用指的是:如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的 可用性,保证业务不会因为数据库的故障而中断。 另外,数据库高可用还要数据一致性,如下: (1) 用作备份、只读副…

数据库集群

目录 主从复制集群单机数据库的问题单机到集群主从复制传统主从复制异步复制半同步复制 组复制(MGR MySQL Group Replication MGR ) 主从复制演示准备两个MySQL服务实例修改主数据库MySQL_A的my.ini中的[mysqld]配置项下的配置如下修改从数据库MySQL_B的…

MySQL数据库的集群方案

1.简介 我们一般应用对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大,有一个思路就是说采用数据库集群的方案: 其中一个是主库,负责写入数据,我们称之为:写库; 其它都是从库&…

MySQL集群解决方案(1):MySQL数据库的集群方案

1、系统架构存在的问题 在我们的系统架构中,DBserver方面我们只是使用了单节点服务,如果面对大并发,海量数据的存储,显然单节点的系统架构将存在很严重的问题,所以接下来,我们将实现MySQL的集群&#xff0c…

C语言回调函数详解及实例

C语言回调函数详解及实例 回调函数:函数 F1 调用函数 F2 的时候,函数 F1 通过参数给函数 F2 传递了另外一个函数 F3 的指针,在函数 F2 执行的过程中,函数F2 调用了函数 F3,这个动作就叫做回调(Callback&…

回调函数

什么是回调函数? 有以下三点 1、自己创建的函数; 2、没有调用; 3、但是函数执行了(在某个条件下)。 例如: 1.定时器函数 var a 1setItercal( function(){aconsole.log(a)},1000)//延时器var a 1setTimeout( functi…

C++中回调函数的一个简单例子?

回调函数应用实例: 1、定义一个Person类 (Person.h)文件: 注意:在这个类中指定了回调函数,回调函数的执行者,和回调函数指针 重要的是 回调函数和回调函数指针是怎么关联的? 2、…

一个简单的jQuery回调函数例子

欢迎扫码加入Java高知群交流 jQuery回调函数简单使用 比如说,我们想要点击某个按钮后触发事件, 先把一些指定内容给隐藏掉, 然后跳出相关信息的对话框。 如果使用普通的方法, 不用回调函数的话, 会有怎么样的效…

【C语言】回调函数

目录 前言 一、回调函数是什么? 二、使用步骤 1.举例 2.库函数中的例子 3.模拟实现qsort()函数 前言 随着我们对C语言的学习以及对指针更加深入的了解,我们避免不了接触到回调函数,以下是关于回调函数的知识分享。 一、回调函数是什么…

C语言回调函数一个简单的例子

回调函数通俗的解释: 普通函数:你所写的函数调用系统函数,你只管调用,不管实现。 回调函数:系统调用你所写的函数,你只管实现,不管调用。 以下是使用C语言实现回调函数的一个例子&a…

JS回调函数——简单易懂有实例

初学js的时候&#xff0c;被回调函数搞得很晕&#xff0c;现在回过头来总结一下什么是回调函数。什么是JS&#xff1f;&#xff08;点击查看&#xff09; 下面先看看标准的解释&#xff1a; <script language"javascript"> 02 function SortNumber( obj, …

C语言回调函数详解(全网最全)

文章目录 一、函数指针1.概念2,如何用函数指针调用函数3.**函数指针作为某个函数的参数**4.函数指针作为函数返回类型5.函数指针数组6.函数指针总结 二、回调函数1.什么是回调函数2 为什么要用回调函数&#xff1f;3 怎么使用回调函数&#xff1f;4.下面是一个四则运算的简单回…

回调函数(简单易懂)

因为今天又遇到新的回调函数的形式 callback && callback()&#xff1b;所以搜了一下回调函数&#xff0c;发现真的好多人写得好复杂啊&#xff0c;看得我昏昏欲睡还是看不懂&#xff0c;还有看到有的人说是 主函数执行完再去执行回调函数&#xff0c;我顿时无语&…