一:原理
简介:
MySQL Group Replication(简称 MGR )是 MySQL 官方于 2016 年 12 月推出的一个全新的高可用与高扩展的解决方案。
组复制是 MySQL 5.7.17 版本出现的新特性,它提供了高可用、高扩展、高可靠的 MySQL 集群服务
MySQL 组复制分单主模式和多主模式,传统的mysql复制技术仅解决了数据同步的问题,MGR 对属于同一组的服务器自动进行协调。对于要提交的事务,组成员必须就全局事务序列中给定事务的顺序达成一致提交或回滚事务由每个服务器单独完成,但所有服务器都必须做出相同的决定
如果存在网络分区,导致成员无法达成事先定义的分割策略,则在解决此问题之前系统不会继续进行,这是一种内置的自动裂脑保护机制MGR由组通信系统( Group Communication System ,GCS ) 协议支持该系统提供故障检测机制、组成员服务以及安全且有序的消息传递 。
组复制流程
首先我们将多个节点共同组成一个复制组,在执行读写(RW)事务的时候,需要通过一致性协议层 (Consensus 层)的同意,也就是读写事务想要进行提交,必须要经过组里“大多数人”(对应 Node 节 点)的同意,大多数指的是同意的节点数量需要大于 (N/2+1),这样才可以进行提交,而不是原发起 方一个说了算。而针对只读(RO)事务则不需要经过组内同意,直接提交即可
组复制:当master挂掉后会选取新的master
注意:节点数量不能超过9台
组复制单主和多主模式
single-primary mode(单写或单主模式)
单写模式 group 内只有一台节点可写可读,其他节点只可以读。当主服务器失败时,会自动选择新的主 服务器
multi-primary mode(多写或多主模式)
组内的所有机器都是 primary 节点,同时可以进行读写操作,并且数据是最终一致的。
二:实战
实现Mysql组复制
#在mysql-node10中
[root@mysql-node10 ~]# rm -fr /data/mysql/
[root@mysql-node10 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=1 #配置server唯一标识号
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY" #禁用指定存储引擎
gtid_mode=ON #启用全局事件标识
enforce_gtid_consistency=ON #强制gtid一致
master_info_repository=TABLE #复制事件数据到表中而不记录在数据目录中
relay_log_info_repository=TABLE
binlog_checksum=NONE #禁止对二进制日志校验
log_slave_updates=ON #打开数据库中继,
#当slave中sql线程读取日志后也会写入到自己的binlog中
log_bin=binlog #重新指定log名称
binlog_format=ROW #使用行日志格式
plugin_load_add='group_replication.so' #加载组复制插件
transaction_write_set_extraction=XXHASH64 #把每个事件编码为加密散列
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" #通知插件正式加入
#或创建的组名
#名称为uuid格式
group_replication_start_on_boot=off #在server启动时不自动启动组复制
group_replication_local_address="172.25.250.10:33061" #指定插件接受其他成员的信息端口(本地地址)
group_replication_group_seeds="172.25.250.10:33061,172.25.250.20:33061,172.25.250.30:33061" #本地地址允许访问成员列表
group_replication_ip_whitelist="172.25.250.0/24,127.0.0.1/8" #主机白名单
#不随系统自启而启动,只在初始成员主机中手动开启,
#需要在两种情况下做设定:1.初始化建组时 2.关闭并重新启动整个组时
group_replication_bootstrap_group=off #不随系统自启而启动
group_replication_single_primary_mode=OFF #使用多主模式
group_replication_enforce_update_everywhere_checks=ON #组同步中有任何改变检测更新
group_replication_allow_local_disjoint_gtids_join=1 #放弃自己信息以master事件为主
#初始化
[root@mysql-node10 ~]# mysqld --user=mysql --initialize
[root@mysql-node10 ~]# /etc/init.d/mysqld start
[root@mysql-node10 ~]# mysql -uroot -p初始化后生成的密码 -e "alter user
root@localhost identified by 'redhat';"
#配置sql
[root@mysql-node10 ~]# mysql -plee
mysql> SET SQL_LOG_BIN=0; ##先关闭日志功能,因为以下设置不需要向组成员同步
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE USER wang@'%' IDENTIFIED BY 'redhat';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO wang@'%';
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 MASTER TO MASTER_USER='wang', MASTER_PASSWORD='redhat' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql>SET GLOBAL group_replication_bootstrap_group=ON; #开启组创建,用以指定初始成员,只在第一台主机中执行
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (2.19 sec)
mysql> set group_replication_start_on_boot=off #关闭组自动创建
mysql> SELECT * FROM performance_schema.replication_group_members;
查一下组信息
mysql> SELECT * FROM performance_schema.replication_group_members;
由于主从的通信是由主机名来通信的,所以需要在每台机子上做本地解析:
vim /etc/hosts
#在复制配置文件到myql-node20和mysql-node30
[root@mysql-node20 & 30 ~]# scp /etc/my.cnf root@172.25.250.20:/etc/my.cnf
[root@mysql-node20 & 30 ~]# scp /etc/my.cnf root@172.25.250.30:/etc/my.cnf
#修改mysql—node20和mysl-node30中的配置
[root@mysql-node20 & 30 ~]# rm -fr /data/mysql/
[root@mysql-node10 ~]# vim /etc/my.cnf
server-id=2 #在30上写3
group_replication_local_address="172.25.250.20:33061" #在30上要写30
#初始化前记得看一下mysql进程,看之前的还在不在
[root@mysql-node3 ~]# ps -ef | grep mysql
[root@mysql-node10 ~]# mysqld --user=mysql --initialize
[root@mysql-node10 ~]# /etc/init.d/mysqld start
[root@mysql-node10 ~]# mysql -uroot -p初始化后生成的密码 -e "alter user root@localhost identified by 'redhat';"
#配置sql
[root@mysql-node20 & 30 ~]# mysql -predhat
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE USER wang@'%' IDENTIFIED BY 'redhat';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO wang@'%';
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 MASTER TO MASTER_USER='wang', MASTER_PASSWORD='redhat' FOR CHANNEL'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (2.19 sec)
mysql> SELECT * FROM performance_schema.replication_group_members;
再看一下组信息
测试:
在每个节点都可以完成读写
三.Mysql的负载均衡
mysql-router(mysql路由)
MySQL Router
是一个对应用程序透明的InnoDB Cluster连接路由服务,提供负载均衡、应用连接故障转移和客户端路由。
利用路由器的连接路由特性,用户可以编写应用程序来连接到路由器,并令路由器使用相应的路由策略 来处理连接,使其连接到正确的MySQL数据库服务器
Mysql route的部署方式
#安装mysql-router
[root@mysql-router ~]# rpm -ivh mysql-router-community-8.4.0-1.el7.x86_64.rpm
#配置mysql-router
[root@mysql-router ~]# vim /etc/mysqlrouter/mysqlrouter.conf
[routing:ro]
bind_address = 0.0.0.0
bind_port = 7001
destinations = 172.25.250.10:3306,172.25.250.20:3306,172.25.250.30:3306
routing_strategy = round-robin
[routing:rw]
bind_address = 0.0.0.0
bind_port = 7002
destinations = 172.25.250.30:3306,172.25.250.20:3306,172.25.250.10:3306
routing_strategy = first-available
[root@mysql-router ~]# systemctl start mysqlrouter.service
#在其他数据库建立测试用户
mysql> CREATE USER wang@'%' IDENTIFIED BY 'redhat';
mysql> GRANT ALL ON *.* TO wang@'%';
测试:
注意:mysql router 并不能限制数据库的读写,访问分流