zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

(5.1)mysql高可用系列——高可用架构方案概述

mysql架构 系列 方案 可用 概述 5.1
2023-09-11 14:21:09 时间

关键词:mysql高可用概述,mysql高可用架构

常用高可用方案

20190918 现在业内常用的MySQL高可用方案有哪些?
目前来说,用的比较多的开源方案分内置高可用与外部实现,内置高可用有如下:
1、官方版本分支:MGR(首推)
2、percona分支:PXC
3、MariaDB:Galera Cluster

外部实现方案:
1、orchestrator(GTID)
2、replication-manager(GTID)
3、MHA(传统复制)
4、MOHA(支持多AZ部署)
5、其他...

 

2020.10.12

  

 

 

【1】Mysql Replication :Mysql复制

【1.1.1】mysql支持的复制类型

  基于binlog的3种模式(详情参考:binlog的3种日志记录模式),oracle在mysql5.5版本收购

  【1.1】statement:基于语句的复制(5.5.6之前默认),主服务器执行的SQL语句,在从服务器执行同样的语句

  【1.2】row:基于行的复制(5.5.7之后默认),把改变的内容复制到从库,而不是把SQL命令在从库重新执行一遍。mysql5.0就开始支持

  【1.3】mixed:混合类型的复制,默认是使用 statement 语句方式复制,一旦发现基于语句无法精确复制时(比如now() 因为主从有延迟导致数据不一致)就会采用基于 row 行的方式复制。

 

  

【1.1.2】mysql的4种同步方式介绍

      以下图片均引用自《深入浅出mysql开发、优化与管理维护》

       

        

  【1.2.1】异步复制(和MSSQL的高性能模式镜像一样):(3.23 native)

       主库只管binlog dump数据到从库,不保证主从完全一致,断电、崩溃等情况会丢失数据。   

      

 

   【1.2.2】全同步复制:

      【2.2.1】核心概念:主从复制,主库要等到从库重做事务并且提交成功,接受到ACK成功确认标识后,主库才能提交事务。

      【2.2.2】与半同步的区别:半同步是只需要持久化到relay log阶段即可返回ACK成功标识给主库,而全同步需要等待从库SQL进程完整的运行完该事务内容才能返回ACK成功标识。

      【2.2.3】原理:

      主库事务写入redo log和 binlog 文件后,binlog dump线程提取binlog数据给IO线程,IO线程把数据加载回从库的relay log文件。

      从库SQL线程开启事务重做应用relay log数据操作,等从库提交完后,返回ACK确认标识,主库才会提交。

  【1.2.3】传统半同步复制:(自5.5开始,插件)

      【1.2.3.1】原理:

        master事务commit 指令已经写入binlog(注意,这里已经提交了,再去同步,只是在等一个ACK)和 binlog 文件后,binlog dump线程提取binlog数据给IO线程,IO线程把数据加载回从库的relay log文件。

      只要IO线程-》slave的relay log已经flush disk 磁盘落地,slave就返回ACK确认标识给master。

      【1.2.3.2】特性:

        这里的commit主库上是已经在 binlog、redo log 中提交了的,其他session都可以看到。

        但需要等待从库返回ACK确认标识才会把事务提交到存储引擎持久化(即 ibdata、ibd等磁盘数据文件)且返回到client一个commit成功的指令。

      【1.2.3.3】宕机情况:

        master上这个事务其实是已经提交了并且落盘master的binlog了,master的其他Session是可以看到这个提交后的事务的,而slave还没有commit。

        这个时候master挂了,master上的数据和slave不一致。master crash后,master根据redo重做提交了这个事务.

        在切换到从后,slave因为没有commit而回滚了这个事务导致数据丢失。导致主从不一致。

      

      

 

 

  【1.2.4】增强半同步复制(mysql 5.7.4及以上才可以用,与MSSQL镜像高安全模式相同):

      与【1.2.3】传统半同步复制大致一样。唯一的区别就是,在事务提交过来后:

      核心区别:主库会等从库在relay log 阶段持久化该事务到该文件后,接受ACK成功确认标识后,再进行提交(commit指令写入binlog/redolog)

        【1.2.4.1】传统的半同步复制:

          master 会把事务在主库先提交了,其他访问可以查看到,只是等从库返回ACK标识才反馈给client 事务提交成功信息。

        【1.2.4.2】增强半同步复制:

          master 只会写binlog,然后等slave的IO线程把事务持久化(flush disk)到 relay log 上后,返回ACK确认标识。

          master收到确认标识后才会commit 写入到binlog 和 redo log,并返回给客户端commit成功的指令。

        【1.2.4.3】宕机情况:

          主库上这个事务因为没有写入redo log,所以这个事务被认为是未提交。master的其他session是不可以看到这个事务的。

          这个时候主库挂了,master上的数据和slave一致,master crash后,slave不丢数据。        

 

  【1.2.5】GTID 复制(mysql 在 5.6.2 及之后开始支持GTID):

      【1.2.5.1】GTID(Global Transaction Identifiers)概念:

        对于一个已提交事务的编号,事务的唯一编号,并且是一个全局唯一的编号。GTID和事务会记录到binlog中,用来标识事务。

        GTID是用来替代以前,传统复制方法(binlog+position),mysql 5.6.2开始支持GTID。

        mysql支持GTID后,一个事务在集群中就不再孤单,在每一个节点中,如果存在具相同标识符的情况,可以避免同一个事务,在同一个节点出现多次的情况。

          (可以初步理解成row模式的,和statement的区别,前者记得是具体做了什么事,后者记录的是位置)

        GTID的出现最直接的效果就是,每一个事物在集群中具有了唯一性的意义,相对于行复制来讲数据安全性更高,故障切换更简单。

      【1.2.5.2】简单案例解释概念:

        比如,当我们一主2从,主出故障后切换到从DB1上去了,那么另外2台机器,需要重新手动构建主从;

        具体为:     

复制代码
-- 使用传统方式构建的主库宕机重新搭建
-- 麻烦点:每台机器的Binlog名字和Postion位置点都不一样,需要重新定位文件在哪里,位置在哪里
change master to 
master_host='xxx',
master_user='xxx',
master_password='xxx',
master_port='xxx',
master_log_file='xxx',
master_log_pos='xxx';

-- 使用GTID方式的主库宕机重新搭建
-- 优势点:每台机器上的GTID都是一样的,不需要管文件是哪个,位置在哪里,可以自动根据GTID定位
change master to 
master_host='xxx',
master_user='xxx',
master_password='xxx',
master_port='xxx',
master_auto_postion=1;
复制代码

 

      【1.2.5.3】GTID的组成

          GTID 是由 server_uuid:Sequence_Number 组成;

            (1)server_uuid:是一个mysql实例的全局唯一表示;存放在 ${datadir}/auto.cnf

            (2)Sequence_Number:是mysql内部的一个事务的标号,一个mysql实例不会重复的序列号(保证服务器内唯一),也表示在该实例上已经提交事务的数量,并且随着事务提交而递增。

            (3)根据GTID可以知道事务最初是在哪个实例上提交的,方便故障排查和切换

  【1.3】复制之间的区别

      

 

【2】MGR(Mysql Group Replication)

  Mysql群组复制(mysql 5.7.19)

  相关介绍参考:https://www.cnblogs.com/luoahong/articles/8043035.html

  【2.1】基本概念介绍

    由MySQL基于Paxos所开发的,基本复制理念如下图

    

 

    所有机器都是主,为了避免数据冲突在执行提交一个事务后,会先进行数据冲突验证,然后才进行binlog写入与relay log复制。

    

由若干个节点共同组成一个复制组,一个事务的提交,必须经过组内大多数节点(N / 2 + 1)决议并通过,才能得以提交。如上图所示,由3个节点组成一个复制组,Consensus层为一致性协议层,在事务提交过程中,发生组间通讯,由2个节点决议(certify)通过这个事务,事务才能够最终得以提交并响应。

引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。组复制依靠分布式一致性协议(Paxos协议的变体),实现了分布式下数据的最终一致性,提供了真正的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案带来了希望。

    除了多master和数据验证以外,可以暂时理解成后面的所有步骤和半同步复制一样。

  【2.2】MGR架构

    (1)整体架构

    

    (2)replication plugin 插件

      

    (3)GCS

      

  【2.3】MGR的模式

    【2.3.1】单主模式(single primary mode)

    (1)单主模式基本架构与形式概念

    

    (2)单主模式的运行机制

      

    【2.3.2】多主同步模式

    (1)多主同步模式的冲突检测(核心是基于主键),这个检测就是certify

      

       这个冲突检测就是最开始运行原理的certify

        

      如果真有主键相同的操作执行了怎么办?先执行的提交,后执行的冲突回滚,如图

        

    (2)多主同步模式下的限制

限制和规则
•仅InnoDB Engine(Transactional and row level lock)
•表必须有主键
•gtid-mode=ON
•binlog格式为Row-based
•对于同一个对象执行DDL和DML应在同一成员上执行,不支持在不同服务器上执行DDL
•不支持具有多级外键依赖关系的表,特别是已定义CASCADING外键约束的表
•不支持“serializable”隔离级别

  【2.4】MGR的监视  

  (1)常用系统表监视  

两个performance_schema表
•replication_group_members
•replication_group_member_stats
本地成员状态
•扩展Replication performance_schema 表
•group_replication_recovery channel information
•group_replication_applier channel information
•新的全局变量
•group_replication_primary_member

  (2)MGR群组复制的高可用性

更好的容错度
群组复制的高可用性
–故障(F)所需的服务器数量(N)N = 2F + 1.
–最多支持9个成员
•允许4个成员故障。


–没有脑裂的问题
仅当大多数成员(N/2+1)在线时,群组才可用,如下图
  

 

  【2.5】 脑裂问题

    (1)什么是脑裂?(2)MGR为什么会出现脑裂?

      (1)什么是脑裂:我理解的就是,一个大脑控制变成了2个大脑控制,各做各的。产生了不同步,不一致的操作与选择。

      (2)MGR为什么会出现脑裂:大多数情况是因为网络连接问题。如下图

        检测网络分区:Performance_Schema.replication_group_members

        有2个可能-》《1》真就另外3台挂掉了  《2》另外3台没挂,是因为和这2台连不上了无法通信

        我们这里说《2》这种情况

        

        即,本来MGR群组的5台机器都能互相连通,突然,S3-S5这3台机器与S1-S2机器失去了连接。

        只有这S1-S2这2台机器被监控到在线,但其他3台机器是多数节点,它们也可能有连接在使用。对于S3-S5而言,S1-S2是宕机概念的。

        然后对于S3-S5而言的MGR是可以正常运行的,就把其S1-S2丢失了。

        这个时候S1-S2 这2台 查询可以正常运行,但不可以进行增删改(如果发生增删改,就无法再次回到MGR群主里了),如下图

           

        如何处理呢?强制指定节点生成一个新的MGR。

          

    【2.6】MGR读取一致性参数解析

      group_replication_consistency8.0.14之后
        •EVENTUAL,BEFORE,AFTER和BEFORE_AND_AFTER


     (1)EVENTUAL(默认值)事务在执行之前不等待先前的事务应用,也不等待其他成员应用其更改。这是8.0.14之前的

          

    (2)BEFORE

      事务将在开始执行之前等待所有先前的事务完成。这可确保此事务将在最新的数据快照上执行,而不用管是哪个成员。

        

    (3)AFTER

      事务将等待其更改已应用于其他成员。这可确保一旦此事务完成,所有后续事务都会读取包含其更改的数据库状态,而不管它们在哪个成员上执行。

        

    (4)BEFORE_AND_AFTER

      •此事务将等到:

          1)所有先前的事务在开始执行之前完成;

          2)其变更已适用于其他成员。这可确保:

            1)此事务将在最新的数据快照上执行;

            2)一旦此事务完成,所有后续事务都会读取包含其更改的数据库状态,而不管它们在哪个成员上执行

        

 

    【2.7】了解MGR节点状态

      参考:https://blog.csdn.net/d6619309/article/details/70432640

 

【3】MHA(Master High Availability)

  主库高可用,实现故障转移与主从分离,在MySQL故障切换过程中。

  MHA能做到在0~30 秒之内自动完成数据库的故障切换操作,并且在故障切换过程中,MHA能在最大程度上保证数据的一致性。

【3.1】MHA的组成概念与部署概念

  MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。

  MHA  Manager可单独部署在一台机器上管理多个master-slave集群,也可以部署在一台slave节点上。

  MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点。

  当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master,整个故障转移过程对应用程序完全透明。

  MHA Manager:

    (1)master自动切换及故障转移命令运行

    (2)其他的帮助脚本运行:手动切换master;master/slave 状态监测

  MHA Node:

    (1)复制主节点的binlog数据

    (2)对比节点的中继日志文件

    (3)无需停止从节点的SQL线程,定时删除中继日志

【3.2】MHA的基本工作原理

  (1)从宕机崩溃的master保存二进制日志事件(binlog events)

  (2)识别含有最新更新的slave;

  (3)应用差异的中继日志到其他的slave;

  (4)应用从master保存的二进制日志事件(binlog events);

  (5)提升一个slave为新的master;

  (6)是其他的slave连接新的master进行复制;

【3.3】MHA常用架构

  服务器资源:

    (1)至少5台PC,其中2台mysql主库,2台mysql从库,1台MHA Monitor

    (2)其中的MHA Monitor 可以选择低配(即为 MHA MANAGER)

    (3)如果不采用F5等作为从库的负载均衡器,可用2台PC SERVER部署LVS 或 HAProxy + Keepalived组合来代替;

    优点:双主热备,读写分离,SLAVE集群可以线性扩展

    缺点:读写分离需要再程序段解决,但Master大批量写操作时会产生主从延时。

  实际架构方案《1》《2》

    《1》1主3从

      数据库层面:一主三从,选定某一台从为故障切换后的主。

      客户端-》VIP-》负载均衡-》中间件读写分离-》主PC1写

                           -》从PC2~PC4读,PC2指定为故障切换的master

    《2》2主2从

      数据库层面:2主构成VIP,现在正在写的主库把所有数据同步到另外3台机器。

            一般情况下,只有一台主工作,另外一台主空闲待机。

【3.4】MHA的优缺点

  优点:

      由Perl语言开发的开源工具

      由master自动监控和故障转移

      master crash 不会导致主从数据不一致

      可以支持基于 GTID的复制模式(MYSQL 5.7)

      MHA在进行故障转移时更不易产生数据丢失

      同一个监控节点可以监控多个集群

      MHA加强了数据的安全性

  缺点:

      需要编写脚本或利用第三方工具来实现VIP的配置

      MHA启动后,只会对主数据库进行监控

      需要基于SSH免认证配置,存在一定的安全隐患

      没有提供从服务器的读负载均衡功能

【3.5】MHA的工具组件中的常用脚本

(1)Manager工具组件:

  masterha_check_ssl:检查MHA的SSH配置

  masterha_check_repl:检查mysql复制

  masterha_manager:启动MHA

  masterha_check_status:检测当前MHA运行状态

  masterha_master_monitor:监测Master是否宕机

  masterha_master_switch:控制故障转移(自动或者手动)

  masterha_conf_host:添加或删除配置的server信息

(2)Node工具组件:(这些通常由MHA Manager的脚本出发,无需人工操作)

  save_binary_logs:保存和复制master的二进制日志

  apply_diff_relay_logs:识别差异的中继日志事件兵并用于其他slave

  filter_mysqlbinlog:清除不必要的rollback事件(MHA已经不再使用它)

  purge_relay_logs:定期清除中继日志(不会阻塞SQL线程)

(3)自定义扩展

  secondary_check_script:通过多条网络路由检测master的可用性;

  master_ip_failover_script:更新application使用的masterip(需要修改)

  shutdown_script:强制关闭master节点

  report_script:发送报告;

  init_conf_load_script:加载初始配置参数;

  master_ip_online_change:更新Master节点IP地址

  

【4】双主KeepAlived

深入参考:https://blog.csdn.net/m0_64632306/article/details/125202856

【4.0】概念

  MySQL的高可用方案有很多,比如Cluster、MMM、MHA、DRBD,以及Oracle官方推出的Fabric等,这些方案各有优劣,但都比较复杂,安装配置有一定难度,对线上库实施动静太大。就我们的具体情况而言,并不需要这么复杂的环境,实施简单、对现有架构影响最小、能迅速解决问题的方案才是最适合的。比如我们现在只是配置了MySQL Replication,加上如Keepalived这样的高可用软件,就能实现我们的需求。

        MySQL架构为Master/Slave,当Master故障时,虚IP漂移到Slave上提供服务,简单环境如图1所示。在这种架构中,故障自动切换以后,需要采取手动操作的方式与新的Master进行复制。当然也可以设置为Active-Passive模式下的双Master复制。

  

 

 

 

  

  利用KeepAlived实现故障转移(功能上类似于MSSQL的镜像,形式上类似于windows的故障转移群集)

【4.1】keepalived 简介

  (4.1.1)起源

  keepalived软件起初是专门为了LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后台又加入了可以实现高可用的VRRP功能。(VRRP:全称 virtual router redundancy protocol,虚拟路由冗余协议)

  因此Keepalived除了能够管理LVS软件外,还可以作为其他服务(如:Nginx/Haproxy/Mysql)的高可用解决方案软件;

  (4.1.2)实现与组成

  keepalived 软件主要是通过VRRP协议实现高可用功能的。

  VRRP是 virtual route redundancyProtocol(虚拟路由器荣誉协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障问题,它能够保证当个别节点宕机时,整个网络可以不间断的运行。

  (4.1.3)常见运作场景

  一个web服务器至少有2台PC运行Keepalived,一台作为主服务器(master),一台作为备份服务器(Backup),但是对外表现为一个虚拟IP,在Keepalived服务政策工作时,主Master节点会不断地向备节点发送(多播的方式,组播地址为224.0.0.18)心跳消息,用以告诉备节点自己还活着。

  当主Master节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续监测到来自主Master节点的心跳,于是调用自身接管程序,接管主Master节点的IP资源及服务。

  而当主Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色。(抢占模式)(也可以设置成非抢占模式,让其保持主,而不释放资源给原主,具体见4.1.7)

  所以,keepAlived,一方面具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可以实现系统网络服务的高可用功能,而且Keepalived是可以工作在网络的 Layer3,4&7,即网络层(IP层),传输层(TCP层),及应用层,再后面就直接在很多场景下代替了原始的LVS软件方案。

  (4.1.4)keepalived服务的三个重要功能

    (1)管理LVS负载均衡软件

    (2)实现LVS集群节点的健康检查

    (3)作为系统网络服务的高可用性(failover)

  

  (4.1.5)Keepalived服务的工作原理

  Keepalived服务对之间通过VRRP进行通信的,VRRP是通过竞选机制来确定主备的(有点像故障转移群集中的投票仲裁形式),主的优先级高于备,因此工作时主会优先获得所有的资源,备节点处于等待状态,当主挂了的时候,备节点就会接管主节点的资源,然后顶替主节点对外服务。

  在Keepalived服务对之间,只有作为主的服务器会一直发送VRRP广播包,告诉备它还活着,此时备不会抢占主,当主不可用(也就是备没有受到VRRP广播包信息),就会启动相关服务接管资源,保证业务的连续性,接管速度最快可以小于1秒。

  (4.1.6)keepalived 的三个核心模块

    分别是core/check/vrrp

    core:keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。

    check:负责健康检查,包括常见的各种检查方式。

    vrrp:是用来实现VRRP协议的;(VRRP:全称 virtual router redundancy protocol,虚拟路由冗余协议)

  (4.1.7)什么是VRRP?

  VRRP,全称 virtual router redundancy protocol,虚拟路由冗余协议。

  VRRP的出现就是为了解决静态路由的单点故障问题,VRRP是通过一种竞选机制来将路由的任务交给某台VRRP路由器的。 

  (1)VRRP是怎么解决通信问题的?

   在现实的网络环境中,两台需要通信的主机(end-host)大多数情况下并没有直接地物理连接。对于这样的情况,它们之间的路由怎么选择?通常有两种方法解决如何选定到达目的主机的下一跳路由问题:

    使用动态路由协议,如RIP、OSPF等。
    配置静态路由。

  
        很明显,在主机上配置动态路由,因为管理、维护成本以及是否支持等诸多问题是不切实际的。那么配置静态路由就变得很流行。

   实际上,这种方式一直沿用至今。但是,路由器,或者说默认网关(default gateway)却经常成为单故障点。就算配置了多个静态路由,却因为必须重启网络才能生效而变得不实用。

        VRRP(虚拟路由冗余协议,Virtual Router Redundancy Protocol)的目的就是为了解决静态路由单点故障问题。

  它通过一种竞选(election)协议动态地将路由任务交给LAN中虚拟路由器中的某台VRRP路由器。这里有两个关键名词:VRRP路由器和虚拟路由器。

    VRRP路由器:VRRP路由器就是一台路由器,只不过上面运行了VRRPD程序来实现VRRP协议而已,是物理的路由器。一台VRRP路由器可以位于多个虚拟路由器中。
    虚拟路由器:所谓虚拟,就是说并不是实际存在的,是一个逻辑而不是物理的路由器。

          虚拟路由器通常由多台VRRP路由器通过某种方式组成,就好像将这些物理路由器都丢到一个池里面去,整个池对外看起来就像是一台路由器,但其实内部有多台。虚拟路由器的标识称为VRID。
                在一个VRRP虚拟路由中,有多台物理的VRRP路由器,但是这多台物理路由并不同时工作,而是由一台称为master的负责路由工作,其它的都是backup。

          master并非一成不变,VRRP协议让每个VRRP路由器参与竞选,最终获胜的就是master。master有一些特权,比如拥有虚拟路由器的IP地址,我们的主机就是用这个IP地址作为静态路由的。

          拥有特权的master要负责转发发送给网关地址的包和响应ARP请求。

 

  (2)VRRP的工作机制
        VRRP通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP多播(multicast)包形式发送的,多播地址为224.0.0.18。虚拟路由器由VRID(范围0-255)和一组IP地址组成,对外表现为一个众所周知的MAC地址:00-00-5E-00-01-{VRID}。所以,在一个虚拟路由器中,不管谁是master,对外都是相同的MAC和IP(称之为VIP)。客户端主机并不需要因为master的改变而修改自己的路由配置,对它们来说,这种主从的切换是透明的。

        在一个虚拟路由器中,只有作为master的VRRP路由器会一直发送VRRP广告包(VRRP Advertisement Message),backup不会抢占master,除非它的优先级更高。

  当master不可用时,backup收不到广告包,多台backup中优先级最高的这台会抢占为master。这种抢占是非常快速的(<1秒),以保证服务的连续性。出于安全性考虑,VRRP包使用了加密协议进行加密

  (3)keepalived的实现模式

  Keepalived通过组播(默认)、单播(自定义),实现keepalived主备推选,工作模式分为抢占和非抢占。

  《1》抢占模式

    主服务器正常工作时,虚拟IP会在主上,备不提供服务,当主服务优先级低于备的时候,备会自动抢占虚拟IP,这时,主提供服务,备提供服务。

    也就是说,抢占模式下,不分主备,只管优先级。

    不管 keepalived.conf 里的 state 配置成 master 还是 backup ,只看谁的priority 优先级高, priority 优先级高的那一个,在故障恢复后,会自动将VIP资源再次抢回来。

  《2》非抢占模式

    这种方式通过参数nopreempt(一般设置在advert_int 的那一行下面)来控制。不管priority优先级,只要master机器发生故障,VIP资源就会被切换到backup上。

    并且,当master机器恢复后,也不会将VIP资源抢回来。除非Backup机器发生故障,才能自动把VIP等资源切换会主库。

    

    nopreempt 这个参数只能用户state为backup的情况,所以在配置的时候要把master和backup的state都设置成backup,这样才会实现keepalived的非抢占模式!

    也就是说

    a)当state状态一个为master,一个为backup的时候,加不加nopreempt 这个参数都是一样的效果。

      即都是根据priority优先级来决定谁抢占VIP资源,属于抢占模式!

    b)当state状态都设置成backup,如果不配置nopreempt参数。

      也是根据priority优先级来决定谁抢占VIP资源,属于抢占模式!

    c)当state状态都设置成backup,如果配置了 nopreempt 参数,那么久不会去考虑priority优先级了。

      是非抢占模式! 即只有VIP当前所在机器发生故障,另一台机器才能接管VIP。 不考虑优先级问题。

 

 

【4.2】Keepalived在MySQL上有什么作用?

  mysql双主复制,即互为Master-Slave(只有一个Master提供写操作),可以实现数据库服务器的热备。

  但一个Master宕机后不能实现动态切换,使用Keepalived,可以通过虚拟IP,实现双主对外的统一接口以及自动检查、失败切换机制,从而实现MySQL数据库的高可用方案。

 

  《1》架构1:主备集群架构(双主HA+keepalived)

  方案:mysql 双主 或者 主从+keepalived 主从自动切换

  服务器:2台PC

  优点:架构简单,节省资源

  缺点:无法线性扩展,主从失败后需要手动恢复主从架构

【4.3】keepalived 脑裂问题与分析解决

脑裂(split-brain):指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。 对于无状态服务的HA,无所谓脑裂不脑裂;但对有状态服务(比如MySQL)的HA,必须要严格防止脑裂。

在高可用HA系统中,当联系2个节点的“心跳线”断开时,本来为一整体,一个VRRP协议组,动作协调的HA系统,就分裂为两个独立的个体。由于相互失去了联系,都以为对方出了故障;

两个节点的HA软件像“连体人”一样,有共同的身体却拥有两个脑袋,争抢“共享资源”身体,争抢服务器里的应用服务,就会发送严重后果,或者共享资源被瓜分,两边服务都起不来或者都起来都为Master,假如两端服务器发生了脑裂现象就会成为各自的Master,会同时读写“共享存储”,导致数据损坏(常见的如数据库轮询着的联机日志出错) 对付HA系统“裂脑”的对策,目前达成共识的的大概有以下几条:    

  1)添加冗余的心跳线,例如:双线条线(心跳线也HA),尽量减少“裂脑”发生几率;    

  2)启用磁盘锁。正在服务一方锁住共享磁盘,“裂脑”发生时,让对方完全“抢不走”共享磁盘资源。

    但使用锁磁盘也会有一个不小的问题,如果占用共享盘的一方不主动“解锁”,另一方就永远得不到共享磁盘。

    现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。于是有人在HA中设计了“智能”锁。即:正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁。平时就不上锁了。    

  3)设置仲裁机制。例如设置参考IP(如网关IP),当心跳线完全断开时,2个节点都各自ping一下参考IP,不通则表明断点就出在本端。

    不仅“心跳”、还兼对外“服务”的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够ping通参考IP的一端去起服务。

    更保险一些,ping不通参考IP的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。

 

脑裂产生的原因
一般来说,裂脑的发生,有以下几种原因:

1) 高可用服务器对之间心跳线链路发生故障,导致无法正常通信

2)因心跳线坏了(包括断了,老化)

3)因网卡及相关驱动坏了,ip配置及冲突问题(网卡直连)

4)因心跳线间连接的设备故障(网卡及交换机)

5)因仲裁的机器出问题(采用仲裁的方案)

6)高可用服务器上开启了 iptables防火墙阻挡了心跳消息传输

7)高可用服务器上心跳网卡地址等信息配置不正确,导致发送心跳失败

8)其他服务配置不当等原因,如心跳方式不同,心跳广插冲突、软件Bug等 提示:Keepalived配置里同一 VRRP实例如果 virtual_router_id两端参数配置不一致也会导致裂脑问题发生

 

iptables导致keepalived脑裂的问题
曾经碰到的一个keepalived脑裂的问题(如果启用了iptables,不设置"系统接收VRRP协议"的规则,就会出现脑裂)

曾经在做keepalived+Nginx主备架构的环境时,当重启了备用机器后,发现两台机器都拿到了VIP。这也就是意味着出现了keepalived的脑裂现象,检查了两台主机的网络连通状态,发现网络是好的。然后在备机上抓包:

# tcpdump -i eth0|grep VRRP
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

22:10:17.146322 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20
22:10:17.146577 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20
22:10:17.146972 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20
22:10:18.147136 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20

 


抓包发现备机能接收到master发过来的VRRP广播,那为什么还会有脑裂现象?

接着发现iptables开启着,检查了防火墙配置。发现系统不接收VRRP协议。于是修改iptables,添加允许系统接收VRRP协议的配置: 自己添加了下面的iptables规则:

-A INPUT -s 192.168.1.0/24 -d 224.0.0.18 -j ACCEPT #允许组播地址通信
-A INPUT -s 192.168.1.0/24 -p vrrp -j ACCEPT #允许VRRP(虚拟路由器冗余协)通信
最后重启iptables,发现备机上的VIP没了。虽然问题解决了,但备机明明能抓到master发来的VRRP广播包,却无法改变自身状态。只能说明网卡接收到数据包是在iptables处理数据包之前。

 

预防keepalived脑裂问题
在实际生产环境中,我们可以从以下几个方面来防止裂脑问题的发生:  

(0) 同时使用串行电缆和以太网电缆连接,同时用两条心跳线路,这样一条线路坏了,另一个还是好的,依然能传送心跳消息。 

(1)可以采用第三方仲裁的方法。由于keepalived体系中主备两台机器所处的状态与对方有关。如果主备机器之间的通信出了网题,就会发生脑裂,此时keepalived体系中会出现双主的情况,产生资源竞争。

(2)一般可以引入仲裁来解决这个问题,即每个节点必须判断自身的状态。最简单的一种操作方法是,在主备的keepalived的配置文件中增加check配置,服务器周期性地ping一下网关,如果ping不通则认为自身有问题 。

(3)最容易的是借助keepalived提供的vrrp_script及track_script实现。如下所示:

#vim /etc/keepalived/keepalived.conf

......

vrrp_script check_local {

script "/root/check_gateway.sh"

interval 5

}

......

track_script {

check_local

}


脚本内容:

# cat /root/check_gateway.sh
#!/bin/sh

VIP=$1
GATEWAY=192.168.1.1
/sbin/arping -I em1 -c 5 -s $VIP $GATEWAY &>/dev/null


check_gateway.sh 就是我们的仲裁逻辑,发现ping不通网关,则关闭keepalived。

推荐自己写脚本,写一个while循环,每轮ping网关,累计连续失败的次数,当连续失败达到一定次数则运行service keepalived stop关闭keepalived服务。

如果发现又能够ping通网关,再重启keepalived服务。最后在脚本开头再加上脚本是否已经运行的判断逻辑,将该脚本加到crontab里面。

该小节参考原文:https://blog.csdn.net/qq_34556414/article/details/107641766

【5】PXC(Percona XtraDB Cluster)

  Galera高可用集群

【6】分库、分表、分库分表分库

【7】MMM(Master-Master replication manager for MySQL)

  是一套支持双主故障切换和双主日常管理的脚本程序

 

【8】mysql innodb cluster

  参考自《mysql高可用解决方案_社区》PDF--出自徐轶韬

【8.1】What is MySQL InnoDB Cluster?


•由以下的组件构成MySQL的高可用框架
•MySQL Group Replication:提供DB的扩展、自动故障转移
•MySQL Router:提供应用程序连接目标的故障转移
•MySQL Shell:设置群组复制的环境、设置Router
•2017年4月12日GA
•以下产品可以单独安装使用
•MySQL 5.7.19 (2017-07-17)
•MySQL Router 2.1.4 (2017-07-24)
•MySQL Shell 1.0.10 (2017-07-28)

 【8.2】mysql innodb cluster 架构概念

  

  

【8.3】组成部分介绍

  【8.3.1】mysql route

    可以实现负载均衡,读写分离,自动故障切换等功能,是原生支持MGR的官网组件产品。

    MySQL Router 能够在不影响现有应用的前提下,将单独的MySQL实例轻易地迁移到具有高可用性的InnoDB分布式集群。

    在8.0的改进   

原生支持InnoDB集群
•获取Group Replication 的架构
•使用存在于各组成员的元数据
•Bootstraps 时设定InnoDB客户端的路由
•智能的将客户端路由到InnoDB集群
•支持多主和单主模式


•重要的改进
•日志
•监控
•性能
•安全性

 

 

  【8.3.2】mysql shell

注意,mysql shell 是8.x 推出的集成功能,是替代mysql utilities(5.7及之前)的产品,并集成了很多新功能(8.x版本已经没有mysql utilities 了)

在mysql innodb cluster中,可以使用它来设计、管理、监控 

多语言: JavaScript, Python, SQL
–支持编写脚本
•支持Document 和关系型数据库模式
•完整的开发和管理API

mysql shell 管理API:

mysql-js> dba.help()
•通过全局对象‘dba’使用MySQL管理接口
•执行DBA的操作
•管理MySQL InnoDBclusters
•Create clusters
•Deploy MySQLinstances
•Get cluster info
•Start/Stop MySQLInstances
•Validate MySQLinstances …

 

【8.4】核心组成部分MGR

【8.4.1】MySQL Group Replication: 它提供些什么功能?

•高可用分布式MySQL数据库服务
•不需人工操作服务器的固障移转
•提供分布式容错能力
•支持多主更新的架构
•自动重配置(加入/移除节点,崩溃,失败)
•自动侦测和处理冲突

【8.4.2】MGR的发展现状与未来趋势

  

  Step1(已实现):实现组复制高可用,现在已经实现

  Step2(正在进行中当前版奔8.0.17):在实现组复制高可用的基础上,实现异步复制做只读,并且异步复制只读从库会随着组复制中的故障转移而自动把异步复制的主库设置成被故障转移的主库。

    总结起来就一句话:MGR里的自动故障转移后,异步复制从库自动连上新主库。详细见图

    

 

  Step3(还没开始实现):基于Step1和Step2下的分片MGR,也就是说把每个分片做一个MGR,再根据步骤1(分片内的MGR实现HA)和步骤2(MGR下的异步复制+自动故障转移后从库自动连上新主库)

    

   最终目标:

    

  

 【8.4.3】MGR/InnnoDB Cluster的当前用户(2019.08.16 记录时间)

  

 

 参考文件

  《mysql高可用解决方案_社区》PDF--徐轶韬

  《深入浅出MySQL数据库开发、优化与管理维护》第2版(唐汉明、翟振兴)

  博客园~关于MGR的博文:https://www.cnblogs.com/luoahong/articles/8043035.html

mysql高可用介绍:https://www.cnblogs.com/GO-NO-1/p/14032679.html

mysql 高可用方案(最全名):https://www.cnblogs.com/wuxu/p/13161438.html