一、初识MGR

置信很多人对MGR这个词比拟生疏,其实MGR(全称 MySQL Group Replication 【MySQL 组复制】)是Oracle MySQL于2016年12月公布MySQL 5.7.17推出的一个全新高可用和高扩大的解决方案。具备以下个性:

  • 高一致性,基于原生复制及Paxos协定的组复制技术,并以插件的形式提供,提供统一数据安全保障;
  • 高容错性,只有不是大多数节点坏掉就能够持续工作,有自动检测机制,当不同节点产生资源争用抵触时,不会呈现谬误,依照先到者优先准则进行解决,并且内置了自动化脑裂防护机制;
  • 高扩展性,节点的新增和移除都是主动的,新节点退出后,会主动从其余节点上同步状态,直到新节点和其余节点保持一致,如果某节点被移除了,其余节点自动更新组信息,主动保护新的组信息;
  • 高灵活性,有单主模式(图1)和多主模式(图2),单主模式下,会主动选主,所有更新操作都在主上进行;多主模式下,所有server都能够同时解决更新操作。

单主模式(图1)

多主模式(图2)

MGR架构图如下所示:次要包含APIs层,组件层,负责协定模块和API+Paxos引擎层形成。

二、MGR技术演进

2.1 主从复制

传统MySQL复制默认提供了一种简略的主从复制办法,这种架构有一个主,以及一个或者多个从,当主节点执行提交事务,而后异步的形式发送到其余从节点,从库从新执行relay log日志内容达到主正本统一的目标,在默认状况下集群所有节点数据都是统一的。

MySQL异步复制

2.2  半同步复制

异步复制存在肯定的数据失落危险,MySQL又在5.6版本中推出半同步复制,在同步数据协定中增加了一个同步操作,这样象征主节点在commit操作,须要确认起码一个从节点确认接管到并且返回ACK,只有这样主节点能力正确提交数据。

MySQL半同步复制

2.3  组复制

MySQL MGR 集群起码3个server节点独特组成的分布式集群,一种share-nothing复制计划,每个server节点都有残缺的正本。

MySQL组复制协定

三、MGR技术个性

3.1 故障检测

组复制自带提供一种故障检测机制,这个机制能报告哪个组成员是无响应的,并且如何判断该成员是否排除集群组。在组复制中故障检测是一种分布式服务。假如服务器A在预约时间段内未收到来自服务器B的音讯,如果组内其余成员也同样未收到来自服务器B的音讯,那么确认判断B产生故障,这样由其余成员断定将失联组成员从集群中剔除。

此时服务器B与其余服务节点都无奈分割。因为无奈达成最小仲裁成员数,处于独立状态,无奈对外提供服务。

3.2 容错

MySQL组复制构建在Paxos分布式算法根底上实现的,以提供不同server之间的分布式协调。因而,它须要大多数server处于活动状态以达到仲裁成员数,从而做出决定。这对系统能够容忍的不影响其本身及其整体性能的故障数量有间接影响。容忍f个故障所需的server数量(n)n = 2 * f + 1。

实际中,这意味着为了容忍一个故障,组必须有三个server。如果一个服务器故障, 依然有两个服务器造成大多数(三分之二)来容许零碎主动地持续运行。然而,如果第二个server意外地宕掉,则该组锁定(只有一个server),因为没有达到少数能够达成选举(不能自己选举本人)。以下是阐明上述公式的小表:

3.3  成员治理

组复制以组视图(Group View,后续简称视图)为根底来进行成员治理,视图个别在Group在一段时间内的成员状态,如果这段时间没有成员变动,也就是说没有成员的退出和退出,一旦有成员退出或者退出组,则视图就发生变化,并且应用视图ID(view id)进行跟踪变动辨别先后工夫,上面咱们来看一张图演示一下:

序号局部,初始化时,第一个视图的序号从1开始,成员只有疏导主一个,为进行初始化节点,当前呈现的任何成员的退出和退出这个序号都须要减少1,能够通过performance\_schema零碎库下的replication\_group\_member\_stats表中查问以后视图。

四、MGR装置体验

理解任何一个新技术从部署开始,装置比较简单,咱们筹备如下测试节点:

10.10.1.214

10.10.1.217

10.10.6.91

装置版本均为最新版本8.0.24,将安装包解压后进行初始化:

su - mysql wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-8.0/mysql-8.0.24-linux-glibc2.12-x86_64.tar tar -xf mysql-8.0.24-linux-glibc2.12-x86_64.tar cd mysql-8.0.24-linux-glibc2.12-x86_64 # 创立配置文件和数据目录 mkdir conf data 初始化数据库并且启动 ./bin/mysqld --initialize --datadir=/home/mysql/mysql-8.0.24-linux-glibc2.12-x86_64/data --basedir=/home/mysql/mysql-8.0.24-linux-glibc2.12-x86_64 ./bin/mysqld_safe --defaults-file=conf/my.cnf &

4.1  通用配置阐明

配置代码

[mysqld]bind-address=0.0.0.0datadir=/home/mysql/mysql-8.0.24-linux-glibc2.12-x86_64/databasedir=/home/mysql/mysql-8.0.24-linux-glibc2.12-x86_64port=3306socket=/home/mysql/mysql-8.0.24-linux-glibc2.12-x86_64/data/mysqld.sockuser=mysql# 每个节点要求不一样server_id=1gtid_mode=ONenforce_gtid_consistency=ONmaster_info_repository=TABLErelay_log_info_repository=TABLEbinlog_checksum=NONElog_slave_updates=ONlog_bin=binlogbinlog_format=ROWinnodb_buffer_pool_size=1g# 8.0 默认值XXHASH64,针对写事务进行哈希解决transaction_write_set_extraction=XXHASH64# 启动加载组复制插件plugin_load_add='group_replication.so'# 集群惟一IDgroup_replication_group_name="8d3cebd8-b132-11eb-8529-0242ac130003"# 是否启动MySQL服务时启动组复制,倡议值:offgroup_replication_start_on_boot=off# 本地IP前面端口33061可自定义,集群通信端口,倡议对立端口group_replication_local_address= "10.10.1.214:33061"# 初始化集群成员列表,可动静批改group_replication_group_seeds= "10.10.1.214:33061,10.10.1.217:33061,10.10.6.91:33061"# 判断是否为疏导组group_replication_bootstrap_group=off# 设置白名单,这里特地留神,如果是同网段能够不必设置,如果是不同网段则须要批改否则通信端口不可拜访loose-group_replication_ip_whitelist='10.10.1.214,10.10.1.217,10.10.6.91'

4.2  单主模式部署

4.2.1  疏导节点初始化

# 创立用户和装置插件 mysql> SET SQL_LOG_BIN=0; Query OK, 0 rows affected (0.00 sec)  mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.01 sec)  mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; Query OK, 0 rows affected (0.00 sec)  mysql> GRANT BACKUP_ADMIN ON *.* TO rpl_user@'%'; Query OK, 0 rows affected (0.00 sec)  mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)  mysql> SET SQL_LOG_BIN=1; Query OK, 0 rows affected (0.00 sec)  mysql> CHANGE REPLICATION SOURCE TO SOURCE_USER='rpl_user', SOURCE_PASSWORD='password' FOR CHANNEL 'group_replication_recovery'; Query OK, 0 rows affected, 2 warnings (0.05 sec)  mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so'; mysql> SHOW PLUGINS; +---------------------------------+----------+--------------------+----------------------+---------+ | Name                            | Status   | Type               | Library              | License | +---------------------------------+----------+--------------------+----------------------+---------+ | group_replication               | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     | +---------------------------------+----------+--------------------+----------------------+---------+ # 启动疏导节点 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, 1 warning (2.33 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 | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 4cf69361-b22b-11eb-a2c9-fa163ebefc6a | 10-10-1-214                                     |        3306 | ONLINE       | PRIMARY     | 8.0.24         | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+

4.2.2  退出从节点

mysql> SET SQL_LOG_BIN=0; Query OK, 0 rows affected (0.00 sec) mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.01 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; Query OK, 0 rows affected (0.03 sec)  mysql> GRANT BACKUP_ADMIN ON *.* TO rpl_user@'%'; Query OK, 0 rows affected (0.00 sec)  mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql> SET SQL_LOG_BIN=1; Query OK, 0 rows affected (0.00 sec) mysql> CHANGE REPLICATION SOURCE TO SOURCE_USER='rpl_user', SOURCE_PASSWORD='password' FOR CHANNEL 'group_replication_recovery'; Query OK, 0 rows affected, 2 warnings (0.05 sec) mysql> START GROUP_REPLICATION; Query OK, 0 rows affected, 1 warning (3.33 sec) # 查看状态 mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST                                     | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 4cf69361-b22b-11eb-a2c9-fa163ebefc6a | 10-10-1-214                                     |        3306 | ONLINE       | PRIMARY     | 8.0.24         | | group_replication_applier | 53f39dba-b22b-11eb-bfdb-fa163e42784d | 10-10-1-217                                     |        3306 | ONLINE       | SECONDARY   | 8.0.24         | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ 2 rows in set (0.00 sec) 其余一个节点执行上述即可,执行实现后查看 mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST                                     | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 4cf69361-b22b-11eb-a2c9-fa163ebefc6a | 10-10-1-214                                     |        3306 | ONLINE       | PRIMARY     | 8.0.24         | | group_replication_applier | 53f39dba-b22b-11eb-bfdb-fa163e42784d | 10-10-1-217                                     |        3306 | ONLINE       | SECONDARY     | 8.0.24         | | group_replication_applier | 56779526-b22b-11eb-a28e-fa163e1f9809 | 10-10-6-91                                      |        3306 | ONLINE       | SECONDARY     | 8.0.24         | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec)

4.3  多主模式部署

多主模式和单主部署形式差不多,只在退出集群时多执行:

set global group_replication_single_primary_mode=off;

单主的都是ON。

4.3.1  疏导节点初始化

mysql> set global group_replication_single_primary_mode=off; 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, 1 warning (2.16 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 | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 4cf69361-b22b-11eb-a2c9-fa163ebefc6a | 10-10-1-214                                     |        3306 | ONLINE       | PRIMARY     | 8.0.24         | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ 1 row in set (0.00 sec)

4.3.2  退出其余节点

mysql> set global group_replication_single_primary_mode=off; Query OK, 0 rows affected (0.00 sec)  mysql> START GROUP_REPLICATION; Query OK, 0 rows affected, 1 warning (3.26 sec) mysql> select * from  performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST                                     | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 4cf69361-b22b-11eb-a2c9-fa163ebefc6a | 10-10-1-214                                     |        3306 | ONLINE       | PRIMARY     | 8.0.24         | | group_replication_applier | 53f39dba-b22b-11eb-bfdb-fa163e42784d | 10-10-1-217                                     |        3306 | ONLINE       | PRIMARY     | 8.0.24         | | group_replication_applier | 56779526-b22b-11eb-a28e-fa163e1f9809 | 10-10-6-91                                      |        3306 | ONLINE       | PRIMARY     | 8.0.24         | +---------------------------+--------------------------------------+-------------------------------------------------+-------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec)

4.4  测试体验

# 在任意节点执行 mysql> show databases; +--------------------+ | Database           | +--------------------+ | information_schema | | mysql              | | performance_schema | | sys                | +--------------------+ 4 rows in set (0.00 sec)  mysql> create database test; Query OK, 1 row affected (0.01 sec)  # 任意节点查问mysql> show databases; +--------------------+ | Database           | +--------------------+ | information_schema | | mysql              | | performance_schema | | sys                | | test               | +--------------------+ 5 rows in set (0.00 sec)

五、利用场景

  • MGR采纳多正本模式,在2N+1个集群中,集群只有N+1个节点还存活,数据库就能稳固对外提供服务,实用于金融场景,因为这些场景数据必须零失落,可用性在4个9甚至5个9。
  • 实用于代替以后主从高可用版本,解决单点写入问题。
  • 针对业务须要弹性扩大节点的基础架构环境,例如公有云。

六、总结

只管MySQL在2016年就推出了MGR该性能,同时咱们也晓得有很多益处,并且有大胆的公司采纳进行测试甚至部署线上环境,据公开材料网易、滴滴都有应用,国内局部商业银行也有应用,但依然有不少人处于张望状态,次要有以下几点起因导致:

需要不是特地强烈

  • 很多业务状况应用MySQL半同步和异步复制足够满足业务要求,配合MHA第三方组件满足了绝大部分场景需要。

分布式新事物

  • 自身分布式这个概念曾经存在多年,然而因为MGR推出年限较短,且咱们搜寻官网bug库任然存在较多未解决的bug。用户应用排查问题较为艰难,且因为分布式设计导致问题复现难也是一种妨碍。

生态不成熟

  • 官网简直没有齐全成熟用来构建整套高可用架构的解决方案,如果想要大规模应用还是须要更加成熟的生态。

任何陈腐事物都有一个被公众承受过程,只是须要工夫筛选和磨砺。

参考文档

https://dev.mysql.com/doc/refman/8.0/en/group-replication.html

作者:vivo互联网数据库团队-Liu Shilin