Mysql之组复制

1.  组复制介绍

    MySQL Group Replication(简称MGR)是MySQL官方于2016年12月推出的一个全新的高可用与高扩展的解决方案。组复制是MySQL5.7版本出现的新特性,它提供了高可用、高扩展、高可靠的MySQL集群服务。MySQL组复制分单主模式和多主模式,mysql 的复制技术仅解决了数据同步的问题,如果 master 宕机,意味着数据库管理员需要介入,应用系统可能需要修改数据库连接地址或者重启才能实现。(这里也可以使用数据库中间件产品来避免应用系统数据库连接的问题,例如 mycat 和 atlas 等产品)。组复制在数据库层面上做到了,只要集群中大多数主机可用,则服务可用,也就是说3台服务器的集群,允许其中1台宕机。

2.  组复制的两种模式

    1.  单主模式

        在单主模式下, 组复制具有自动选主功能,每次只有一个 server成员接受更新;        

    2.  多主模式

        在多主模式下, 所有的 server 成员都可以同时接受更新;

3.  组复制原理

    组复制是一种可用于实现容错系统的技术。 复制组是一个通过消息传递相互交互的server集群。通信层提供了原子消息(atomic message)和完全有序信息交互等保障机制,实现了基于复制协议的多主更新。复制组由多个 server成员构成,并且组中的每个server 成员可以独立地执行事务。但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。句话说, 对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。准确地说,在始发 server 上,当事务准备好提交时,该 server 会广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后会为该事务建立一个全局的顺序。最终,这意味着所有 server 成员以相同的顺序接收同一组事务。因此, 所有 server 成员以相同的顺序应用相同的更改,以确保组内一致。

    基于组的复制(Group-basedReplication)是一种被使用在容错系统中的技术。Replication-group(复制组)是由能够相互通信的多个服务器(节点)组成的。在通信层,Groupreplication实现了一系列的机制:比如原子消息(atomicmessage delivery)和全序化消息(totalorderingof messages)。这些原子化,抽象化的机制,为实现更先进的数据库复制方案提供了强有力的支持。MySQL Group Replication正是基于这些技术和概念,实现了一种多主全更新的复制协议。简而言之,一个Replication-group就是一组节点,每个节点都可以独立执行事务,而读写事务则会在于group内的其他节点进行协调之后再commit。因此,当一个事务准备提交时,会自动在group内进行原子性的广播,告知其他节点变更了什么内容/执行了什么事务。这种原子广播的方式,使得这个事务在每一个节点上都保持着同样顺序。这意味着每一个节点都以同样的顺序,接收到了同样的事务日志,所以每一个节点以同样的顺序重演了这些事务日志,最终整个group保持了完全一致的状态。然而,不同的节点上执行的事务之间有可能存在资源争用。这种现象容易出现在两个不同的并发事务上。

    假设在不同的节点上有两个并发事务,更新了同一行数据,那么就会发生资源争用。面对这种情况,GroupReplication判定先提交的事务为有效事务,会在整个group里面重演,后提交的事务会直接中断,或者回滚,最后丢弃掉。因此,这也是一个无共享的复制方案,每一个节点都保存了完整的数据副本。看下图描述了具体的工作流程,能够简洁的和其他方案进行对比。这个复制方案,在某种程度上,和数据库状态机(DBSM)的Replication方法比较类似。

4.  组复制特点

    高一致性
      基于原生复制及 paxos 协议的组复制技术,并以插件的方式提供,提供一致数据安全保证。确保组内数据最终一致性【重要】(通过分布式协议和分布式recovery机制保证);
    高容错性
      确保组内高可用。只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制;
    高扩展性
      良好的扩展能力,可动态增删节点,组成员自动管理。节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息;
    高灵活性
      有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;
      多主模式下,所有 server 都可以同时处理更新操作。
      多写,写冲突检测

5.  组复制故障检测

    故障检测是提供关于哪些 server 可能已死的信息(猜测)的分布式服务。 某个 server 无响应时触发猜测,组中其余成员进行协调决定以排除给定成员。如果某个 server 与组的其余成员隔离,则它会怀疑所有其他 server 都失败了。由于无法与组达成协议(因为它无法确保仲裁成员数),其怀疑不会产生后果。当服务器以此方式与组隔离时,它无法执行任何本地事务。 在线 server 列表通常称为视图,新成员server的加入离开,无论是自愿还是被迫的离开,该组都会动态地重新规划其配置,并触发视图更新。

6.  组复制的限制

    -  存储引擎必须为Innodb,即仅支持InnoDB表,并且每张表一定要有一个主键,用于做write set的冲突检测;
    -  每个表必须提供主键;
    -  只支持ipv4,网络需求较高;
    -  必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set;
    -  COMMIT可能会导致失败,类似于快照事务隔离级别的失败场景;
    -  目前一个MGR集群组最多支持9个节点;
    -  不支持外键于save point特性,无法做全局间的约束检测与部分部分回滚;
    -  二进制日志binlog不支持Replication event checksums;
    -  多主模式(也就是多写模式) 不支持SERIALIZABLE事务隔离级别;
    -  多主模式不能完全支持级联外键约束;
    -  多主模式不支持在不同节点上对同一个数据库对象并发执行DDL(在不同节点上对同一行并发进行RW事务,后发起的事务会失败); 

7.  组复制优点

    1) 在master-slave之间实现了强一致性;
      对于只读事务,组间实例无需进行通讯,就可以处理事务;对于读写(RW)事务,组内所有节点必须经过通讯,共同决定事务提交与否。

    2) 事务冲突处理
      在高并发的多写模式下,节点间事务的提交可能会产生冲突,比如,两个不同的事务在两个节点上操作了同一行数据,这个时候就会产生冲突。首先,Group Replication(GR)能够识别到这个冲突,然后对此的处理是,依赖事务提交的时间先后顺序,先发起提交的节点能够正确提交,而后面的提交,会失败

    3) 故障检测
      MGR自带故障检测机制,可以识别组内成员是否挂掉(组内节点心跳检测)。当一个节点失效,将由其他节点决定是否将这个失效的节点从group里面剔除。

    4) 组成员管理
      MGR需要维护组内节点的状态(ONLINE,RECOVERING,OFFLINE),对于失效的节点,由其他节点决定是否剔除。对于新加入的节点,需要维护它的视图与其他节点的视图保持一致。

    5) 容错能力
      MGR基于分布式一致性算法实现,一个组允许部分节点挂掉,只要保证大多数节点仍然存活并且之间的通讯是没有问题的,那么这个组对外仍然能够提供服务!假设一个MGR由2n+1个节点,那么允许n个节点失效,这个MGR仍然能够对外提供服务。比如有3个节点组成的一个GR,可允许1个节点失效,这个GR仍然能够提供服务。

    6) 部署方便简单。

8.  组复制模式介绍

    1.  单写模式

        单写模式group内只有一台节点可写可读,其他节点只可以读。

        对于group的部署,需要先跑起primary节点(即那个可写可读的节点,read_only = 0)然后再跑起其他的节点,并把这些节点一一加进group。其他的节点就会自动同步primary节点上面的变化,然后将自己设置为只读模式(read_only = 1)。当primary节点意外宕机或者下线,在满足大多数节点存活的情况下,group内部发起选举,选出下一个可用的读节点,提升为primary节点。primary选举根据group内剩下存活节点的UUID按字典序升序来选择,即剩余存活的节点按UUID字典序排列,然后选择排在最前的节点作为新的primary节点。

        单写模式部署(单机多实例)
          在一个节点上运行三个MySQL实例,然后把其中一个实例部署为主,其他两个节点部署为从;主写,从读;这种模式适用于实验和自己练习。

        特别重要:在切换primary期间,mysql group不会处理应用重连接到新的主,这需要应用层自己或者由另外的中间件层(proxy or router)去保证!       

    2.  多写模式

        group内的所有机器都是primary节点,同时可以进行读写操作,并且数据是最终一致的。
        该模式不好的地方在于: 非rpm包安装,目前使用rpm方式没有配置成功;启动还是处于手动方式,可以编写sys V方式启动脚本;性能上面没有做压测。                

        多机多写部署
          在三个节点上分别部署MySQL实例,每个节点都接收写请求;额外可以加入一个节点,测试节点的动态增加。 

9.  基于GTID的组复制分布式集群的环境部署(多机多写模式)

    1.  运行环境

角色 IP地址 Server_id 数据状态 操作系统
MGR-node1 192.168.1.200 200 Mysql实例 CentOS7.4
MGR-node2 192.168.1.210 210 Mysql实例 CentOS7.4
MGR-node3 192.168.1.201 201 Mysql实例 CentOS7.4

 

    2.  准备工作

        1.  关闭防火墙,关闭selinux,配置/etc/hosts文件(一定要配置)

        2.  安装Mysql5.7,略

    3.  MGR组复制配置

        1.  MGR-node1配置

           1.  先给MGR起一个组名,不能使用主机的GTID,可以使用mysql的uuid作为组名

           2.  my.cnf的设置

[mysqld]
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
       
symbolic-links = 0
       
log-error = /var/log/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid
   
#GTID:
server_id = 200
gtid_mode = on
enforce_gtid_consistency = on
   
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
       
#binlog
log_bin = mysql-bin
log-slave-updates = 1
binlog_format = row
sync-master-info = 1
sync_binlog = 1
      
#relay log
skip_slave_start = 1
   
transaction_write_set_extraction=XXHASH64      #以便在server收集写集合的同时将其记录到二进制日志。写集合基于每行的主键,并且是行更改后的唯一标识此标识将用于检测冲突。
loose-group_replication_group_name="5db40c3c-180c-11e9-afbf-005056ac6820"     #组的名字可以随便起,但不能用主机的GTID! 所有节点的这个组名必须保持一致!,使用node1的UUID
loose-group_replication_start_on_boot=off    #为了避免每次启动自动引导具有相同名称的第二个组,所以设置为OFF。
loose-group_replication_local_address= "192.168.1.200:24901"
loose-group_replication_group_seeds= "192.168.1.200:24901,192.168.1.210:24901,192.168.1.201:24901"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=off      #关闭单主模式的参数(本例测试时多主模式,所以关闭该项)
loose-group_replication_enforce_update_everywhere_checks=on    #开启多主模式的参数
loose-group_replication_ip_whitelist="192.168.1.0/24,127.0.0.1/8"    # 允许加入组复制的客户机来源的ip白名单

           3.  复制my.cnf到另外两台机器

           4.  重启mysql服务

           5.  配置复制组插件

               1.  SET SQL_LOG_BIN=0;   不记录二进制日志

               2.  GRANT REPLICATION SLAVE ON *.* TO rpl_slave@'%' IDENTIFIED BY 'slave@123';  创建复制用户

                    flush privileges;

               3.  reset master;  重置日志

               4.  SET SQL_LOG_BIN=1;  记录二进制日志

               5.  CHANGE MASTER TO MASTER_USER='rpl_slave', MASTER_PASSWORD='slave@123' FOR CHANNEL 'group_replication_recovery';  配置复制

               6.  INSTALL PLUGIN group_replication SONAME 'group_replication.so';  安装复制组插件

               7.  show plugins;  查看插件是否安装成功 

           6.  启动组复制

mysql> SET GLOBAL group_replication_bootstrap_group=ON;         #只在第一个节点执行这个步骤
Query OK, 0 rows affected (0.00 sec)
    
mysql> START GROUP_REPLICATION;
ERROR 3096 (HY000): The START GROUP_REPLICATION command failed as there was an error when initializing the group communication layer.
    
如上出现如上错误,则需要先stop之后做才可以
mysql> STOP GROUP_REPLICATION;
Query OK, 0 rows affected (0.00 sec)
   
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)
   
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (2.14 sec)
   
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)
   
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 317e2aad-1565-11e9-9c2e-005056ac6820 | MGR-node1   |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.00 sec)
    
比如要保证上面的group_replication_applier的状态为"ONLINE"才对!                       

        2.  MGR-node2配置

            1.  基本上与node1相同的过程

            2.  只是启动组复制的时候,只需要执行命令

                START GROUP_REPLICATION;

            3.  查看复制组成员

                SELECT * FROM performance_schema.replication_group_members;    

        3.  MGR-node3配置

            1.  与node2的配置完全一样

    4.  组复制数据同步测试

        1.  在任意节点添加删除数据,其他节点都会同步数据

    5.  组复制故障测试

        1.  当组内的某个节点发生故障时,会自动从将该节点从组内踢出,与其他节点隔离。剩余的节点之间保持主从复制的正常同步关系。当该节点的故障恢复后,只需手动激活组复制即可(即执行"START GROUP_REPLICATION;");

        2.  要是三个节点都发生故障的话,在节点的故障都恢复后,需要手动重新做组复制           

一个节点
mysql> reset master;
mysql> SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='rpl_slave', MASTER_PASSWORD='slave@123' FOR CHANNEL 'group_replication_recovery';
mysql> STOP GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
mysql> SELECT * FROM performance_schema.replication_group_members;
  
第二个节点
mysql> reset master;
mysql> SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='rpl_slave', MASTER_PASSWORD='slave@123' FOR CHANNEL 'group_replication_recovery';
mysql> START GROUP_REPLICATION;
mysql> SELECT * FROM performance_schema.replication_group_members;
  
第三个节点
mysql> reset master;
mysql> SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='rpl_slave', MASTER_PASSWORD='slave@123' FOR CHANNEL 'group_replication_recovery';
mysql> START GROUP_REPLICATION;
mysql> SELECT * FROM performance_schema.replication_group_members;

  

                  

      

posted @ 2022-12-16 11:29  奋斗史  阅读(1141)  评论(0)    收藏  举报