vlambda博客
学习文章列表

MySQL mgr+mysqlrouter高可用架构及配置


一、MySQL Group Replication

        mysql官方基于组复制概念并充分参考MariaDB Galera Cluster和Percona XtraDB Cluster结合而来的新的高可用集群架构。只支持5.7以上版本

mgr 优点:

高一致性,基于原生复制及paxos协议的组复制技术.

高容错性,有自动检测机制,当出现宕机后,会自动剔除问题节点,其他节点可以正常使用(类似zk集群),当不同节点产生资源争用冲突时,会按照先到先得处理,并且内置了自动化脑裂防护机制.

高扩展性,可随时在线新增和移除节点,会自动同步所有节点上状态,直到新节点和其他节点保持一致,自动维护新的组信息.

高灵活性,直接插件形式安装(5.7.17后自带.so插件),有单主模式和多主模式,单主模式下,只有主库可以读写,其他从库会加上super_read_only状态,只能读取不可写入,出现故障会自动选主.


缺点:目前不太稳定,太新有BUG(如新加入集群宕机,并行复制有不一致bug)、管理不方便(需配合mysql-shell)


注意:多主模式下最好有三台以上的节点,单主模式则视实际情况而定,不过同个Group最多节点数为9.

服务器配置尽量保持一致,因为和PXC一样,也会有"木桶短板效应".

需要特别注意,mysql数据库的服务端口号和MGR的服务端口不是一回事,需要区分开来.


二、MGR搭建

   1、配置三个docker容器,配置之前需要配置一个network方便容器间互相连接

        docker  network create mysql_group

   2、运行容器指令

       master:

      docker run --name master -v /Users/drmac/mysql/master:/var/lib/mysql -v /Users/drmac/mysql/master.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 --network mysql_group  --network-alias master  -d mysql  


     slave-1 

docker run --name slave-1 -v /Users/drmac/mysql/slave-1:/var/lib/mysql -v /Users/drmac/mysql/slave-1.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=root -p 3307:3306 --network mysql_group --network-alias slave-1  -d mysql


     slave-2:

  docker run --name slave-2 -v /Users/drmac/mysql/slave-2:/var/lib/mysql -v /Users/drmac/mysql/slave-2.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=root -p 3308:3306 --network mysql_group --network-alias slave-2  -d mysql


启动三个容器,数据文件和配置文件分别挂载到本地磁盘,方便配置管理


3.my.cnf配置


 master:

[mysqld]

# 开启GTID,必须开启

gtid_mode=on

# 强制GTID的一致性

enforce-gtid-consistency=on

# binlog格式,MGR要求必须是ROW

binlog_format=row

# server-id必须是唯一的

server-id=1

# MGR使用乐观锁,所以官网建议隔离级别是RC,减少锁粒度

transaction_isolation=READ-COMMITTED

# 因为集群会在故障恢复时互相检查binlog的数据,

# 所以需要记录下集群内其他服务器发过来已经执行过的binlog,按GTID来区分是否执行过.

log-slave-updates=1

# binlog校验规则,5.6之后的高版本是CRC32,低版本都是NONE,但是MGR要求使用NONE

binlog_checksum=NONE

# 基于安全的考虑,MGR集群要求复制模式要改成slave记录记录到表中,不然就报错

master_info_repository=TABLE

# 同上配套

relay_log_info_repository=TABLE

# 记录事务的算法,官网建议设置该参数使用 XXHASH64 算法

transaction_write_set_extraction = XXHASH64

# 相当于此GROUP的名字,是UUID值,不能和集群内其他GTID值的UUID混用,可用uuidgen来生成一个新的,

# 主要是用来区分整个内网里边的各个不同的GROUP,而且也是这个group内的GTID值的UUID

loose-group_replication_group_name = 'cc5e2627-2285-451f-86e6-0be21581539f'

#是否随服务器启动而自动启动组复制,不建议直接启动,怕故障恢复时有扰乱数据准确性的特殊情况

loose-group_replication_start_on_boot = OFF

loose-group_replication_local_address = 'master:33066'

loose-group_replication_group_seeds = 'master:33066,salve-1:33066,slave-2:33066'

# 开启引导模式,添加组成员,用于第一次搭建MGR或重建MGR的时候使用,只需要在集群内的其中一台开启,

loose-group_replication_bootstrap_group = OFF

# 是否启动单主模式,如果启动,则本实例是主库,提供读写,其他实例仅提供读,如果为off就是多主模式了

#loose-group_replication_single_primary_mode = off

# 多主模式下,强制检查每一个实例是否允许该操作,如果不是多主,可以关闭

#loose-group_replication_enforce_update_everywhere_checks = on

#mgr需要帮各个节点加入白名单,否则集群不成功

loose-group_replication_ip_whitelist="172.20.0.2/24,172.20.0.3/24,172.20.0.4/24";


log-bin=mysql-bin

pid-file        = /var/run/mysqld/mysqld.pid

socket          = /var/run/mysqld/mysqld.sock

datadir         = /var/lib/mysql

secure-file-priv= NULL

default_authentication_plugin=mysql_native_password

# Disabling symbolic-links is recommended to prevent assorted security risks

symbolic-links=0


# Custom config should go here

!includedir /etc/mysql/conf.d/



slave1 :

[mysqld]

# 开启GTID,必须开启

gtid_mode=on

# 强制GTID的一致性

enforce-gtid-consistency=on

# binlog格式,MGR要求必须是ROW,不过就算不是MGR,也最好用row

binlog_format=row

# server-id必须是唯一的

server-id=2

# MGR使用乐观锁,所以官网建议隔离级别是RC,减少锁粒度

transaction_isolation=READ-COMMITTED

# 因为集群会在故障恢复时互相检查binlog的数据,

# 所以需要记录下集群内其他服务器发过来已经执行过的binlog,按GTID来区分是否执行过.

log-slave-updates=1

# binlog校验规则,5.6之后的高版本是CRC32,低版本都是NONE,但是MGR要求使用NONE

binlog_checksum=NONE

# 基于安全的考虑,MGR集群要求复制模式要改成slave记录记录到表中,不然就报错

master_info_repository=TABLE

# 同上配套

relay_log_info_repository=TABLE

# 记录事务的算法,官网建议设置该参数使用 XXHASH64 算法

transaction_write_set_extraction = XXHASH64

# 相当于此GROUP的名字,是UUID值,不能和集群内其他GTID值的UUID混用,可用uuidgen来生成一个新的,

# 主要是用来区分整个内网里边的各个不同的GROUP,而且也是这个group内的GTID值的UUID

loose-group_replication_group_name = 'cc5e2627-2285-451f-86e6-0be21581539f'

#是否随服务器启动而自动启动组复制,不建议直接启动,怕故障恢复时有扰乱数据准确性的特殊情况

loose-group_replication_start_on_boot = OFF

loose-group_replication_local_address = 'slave-1:33066'

loose-group_replication_group_seeds = 'master:33066,slave-1:33066,slave-2:33066'

# 开启引导模式,添加组成员,用于第一次搭建MGR或重建MGR的时候使用,只需要在集群内的其中一台开启,

#loose-group_replication_bootstrap_group = OFF

# 是否启动单主模式,如果启动,则本实例是主库,提供读写,其他实例仅提供读,如果为off就是多主模式了

#loose-group_replication_single_primary_mode = off

# 多主模式下,强制检查每一个实例是否允许该操作,如果不是多主,可以关闭

#loose-group_replication_enforce_update_everywhere_checks = on

loose-group_replication_ip_whitelist="172.20.0.2/24,172.20.0.3/24,172.20.0.4/24";



log-bin=mysql-bin

pid-file        = /var/run/mysqld/mysqld.pid

socket          = /var/run/mysqld/mysqld.sock

datadir         = /var/lib/mysql

secure-file-priv= NULL

default_authentication_plugin=mysql_native_password

# Disabling symbolic-links is recommended to prevent assorted security risks

symbolic-links=0


# Custom config should go here

!includedir /etc/mysql/conf.d/


slave-2配置和slave-1一致 (注意server_id和group_replication_local_address修改即可)

 server_idgroup_replication_local_address不同数据库是不同的,其余要保持相同,host后面跟的端口号是自定义的,只要保证和本机的端口不冲突就好


4、配置master


  4.1创建复制账号(每个节点都需要创建账号,并给REPLICATION 、SLAVE角色)

mysql> SET SQL_LOG_BIN=0;

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY '[email protected]';

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1;


  4.2配置频道

 mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='[email protected]'  FOR CHANNEL 'group_replication_recovery';


  4.3安装复制插件 (MGR在mysql5.7.17版本之后就都是自带插件了,只是没有安装上而已,和半同步插件一个套路,所以默认是没有选项。所有集群内的服务器都必须安装MGR插件才能正常使用该功能)

  INSTALL PLUGIN group_replication SONAME 'group_replication.so';


 4.4 开启组复制(master节点)

  SET GLOBAL group_replication_bootstrap_group=ON;

  START GROUP_REPLICATION;

  SET GLOBAL group_replication_bootstrap_group=OFF;


  4.5查看组状态

select * from `performance_schema`.replication_group_members


5、配置slave-1


 5.1创建复制账号(每个节点都需要创建账号,并给REPLICATION 、SLAVE角色)

mysql> SET SQL_LOG_BIN=0;

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY '[email protected]';

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1;


  5.2配置频道

 mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='[email protected]'  FOR CHANNEL 'group_replication_recovery';


  5.3安装复制插件 (MGR在mysql5.7.17版本之后就都是自带插件了,只是没有安装上而已,和半同步插件一个套路,所以默认是没有选项。所有集群内的服务器都必须安装MGR插件才能正常使用该功能)

  INSTALL PLUGIN group_replication SONAME 'group_replication.so';


 5.4 加入节点

注意:加入节点需要开启如下参数

  SET GLOBALgroup_replication_allow_local_lower_version_join=ON

  START GROUP_REPLICATION;


5.5查看组状态

select * from `performance_schema`.replication_group_members

MySQL mgr+mysqlrouter高可用架构及配置


6、配置slave-2

 

 6.1创建复制账号(每个节点都需要创建账号,并给REPLICATION 、SLAVE角色)

mysql> SET SQL_LOG_BIN=0;

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY '[email protected]';

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1;


  6.2配置频道

 mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='[email protected]'  FOR CHANNEL 'group_replication_recovery';


  6.3安装复制插件 (MGR在mysql5.7.17版本之后就都是自带插件了,只是没有安装上而已,和半同步插件一个套路,所以默认是没有选项。所有集群内的服务器都必须安装MGR插件才能正常使用该功能)

  INSTALL PLUGIN group_replication SONAME 'group_replication.so';


 6.4 加入节点

注意:加入节点需要开启如下参数

  SET GLOBALgroup_replication_allow_local_lower_version_join=ON

  START GROUP_REPLICATION;


6.5查看组状态

select * from `performance_schema`.replication_group_members

MySQL mgr+mysqlrouter高可用架构及配置



注意如果master中已经存在数据,需要同步,正常情况需要备份主库数据到从库

在做备份恢复的时候,有时需要恢复出来的 MySQL 实例可以作为从库连上原来的主库继续复制,这就要求从备份恢复出来的 MySQL 实例拥有和主数据库数据一致的 gtid_executed 值。

 备份语句:

mysqldump -h localhost -uroot -proot --all-databases --single-transaction --master-data  --triggers --routines --events > /home/dump.sql


slave-1 slave-2分别恢复数据

mysql -h localhost -uroot -proot  -P 3307

mysql -h localhost -uroot -proot  -P 3308


三、MySQL router中间件


MySQL Router是轻量级的中间件,可在您的应用程序与任何后端MySQL Server之间提供透明的路由。它可用于多种使用案例,例如通过有效地将数据库流量路由到适当的后端MySQL服务器来提供高可用性和可伸缩性。可插拔架构还使开发人员能够针对自定义用例扩展MySQL Router。

故障转移

通常,高可用性的MySQL设置由一个主服务器和多个从服务器组成,如果MySQL主服务器不可用,则由应用程序来处理故障转移。使用MySQL Router,将基于负载平衡策略透明地路由应用程序连接,而无需实现自定义应用程序代码。

负载均衡

MySQL Router通过在服务器池中分布数据库连接来提供额外的可伸缩性和性能。例如,如果您有一组复制的MySQL服务器,则MySQL Router可以循环方式将应用程序连接分配给它们。

可插拔架构

MySQL Router的可插入体系结构使MySQL开发人员可以轻松扩展产品的附加功能,并为MySQL用户提供创建自己的自定义插件的能力,从而提供无限的可能性。MySQL Router当前随附许多核心插件,包括:

l连接路由插件,它执行基于连接的路由,这意味着它将MySQL数据包转发到后端服务器,而无需检查或修改它们,从而提供最大的吞吐量。

l元数据高速缓存插件,它提供了透明的客户端负载平衡,路由,和故障转移到组复制和InnoDB群集

 

 1.mysqlrouter启动

 mysqlrouter --bootstrap root@localhost:3310 --directory /Users/drmac/mysqlrouter/ --conf-use-sockets

 mysqlrouter -c /Users/drmac/mysqlrouter/mysqlrouter.conf &


DRdeMacBook-Air:3310 drmac$ mysqlrouter --bootstrap root@localhost:3320 --directory /Users/drmac/mysqlrouter/ --conf-use-sockets --force

Please enter MySQL password for root:

# Reconfiguring MySQL Router instance at '/Users/drmac/mysqlrouter'...


- Checking for old Router accounts

 - Found old Router accounts, removing

- Creating mysql account 'mysql_router1_i68kebi6fq9l'@'%' for cluster management

- Storing account in keyring

- Adjusting permissions of generated files

- Creating configuration /Users/drmac/mysqlrouter/mysqlrouter.conf


# MySQL Router configured for the InnoDB cluster 'testCluster'


After this MySQL Router has been started with the generated configuration


    $ mysqlrouter -c /Users/drmac/mysqlrouter/mysqlrouter.conf


the cluster 'testCluster' can be reached by connecting to:


## MySQL Classic protocol


- Read/Write Connections: localhost:6446, /Users/drmac/mysqlrouter/mysql.sock

- Read/Only Connections:  localhost:6447, /Users/drmac/mysqlrouter/mysqlro.sock


## MySQL X protocol


- Read/Write Connections: localhost:64460, /Users/drmac/mysqlrouter/mysqlx.sock

- Read/Only Connections:  localhost:64470, /Users/drmac/mysqlrouter/mysqlxro.sock



2.mysqlrouter 配置

# File automatically generated during MySQL Router bootstrap

[DEFAULT]

logging_folder=/Users/drmac/mysqlrouter/log

runtime_folder=/Users/drmac/mysqlrouter/run

data_folder=/Users/drmac/mysqlrouter/data

keyring_path=/Users/drmac/mysqlrouter/data/keyring

master_key_path=/Users/drmac/mysqlrouter/mysqlrouter.key

connect_timeout=15

read_timeout=30

dynamic_state=/Users/drmac/mysqlrouter/data/state.json


[logger]

level = INFO


[metadata_cache:testCluster]

router_id=1

user=mysql_router1_i68kebi6fq9l

metadata_cluster=testCluster

ttl=0.5

use_gr_notifications=0


[routing:testCluster_default_rw]

bind_address=0.0.0.0

bind_port=6446

socket=/Users/drmac/mysqlrouter/mysql.sock

destinations=metadata-cache://testCluster/default?role=PRIMARY

routing_strategy=first-available

protocol=classic


[routing:testCluster_default_ro]

bind_address=0.0.0.0

bind_port=6447

socket=/Users/drmac/mysqlrouter/mysqlro.sock

destinations=metadata-cache://testCluster/default?role=SECONDARY

routing_strategy=round-robin-with-fallback

protocol=classic


[routing:testCluster_default_x_rw]

bind_address=0.0.0.0

bind_port=64460

socket=/Users/drmac/mysqlrouter/mysqlx.sock

destinations=metadata-cache://testCluster/default?role=PRIMARY

routing_strategy=first-available

protocol=x


[routing:testCluster_default_x_ro]

bind_address=0.0.0.0

bind_port=64470

socket=/Users/drmac/mysqlrouter/mysqlxro.sock

destinations=metadata-cache://testCluster/default?role=SECONDARY

routing_strategy=round-robin-with-fallback

protocol=x



MySQL路由器配置了四个端口和四个套接字。默认情况下添加端口,并通过传入添加套接字 --conf-use-sockets。名为“ testCluster”的InnoDB群集是元数据的来源,并且destinations使用InnoDB群集元数据缓存来动态配置主机信息。相关的命令行选项:


--conf-use-sockets:有选择地为所有四种连接类型启用UNIX域套接字


--conf-skip-tcp:有选择地禁用TCP端口,--conf-use-sockets如果只希望使用套接字,则可以使用该选项 。


--conf-base-port:(可选)更改端口范围,而不使用默认端口。这将为经典读写(PRIMARY)连接设置端口,默认为 6446。


--conf-bind-address:(可选)更改每个路由的bind_address值。




3.登录mysql



四、MySQLshell 管理mgr


模式切换

默认情况下mgr为单主模式,切换可以从mysqlshell直接切换

cluster.switchToMultiPrimaryMode()


自动切换为多主模式


多主模式切换为单主模式:

 cluster.switchToSinglePrimaryMode()





1、创建cluster

  mysql-js> shell.connect('root@localhost:3310')


  mysql-js> var cluster = dba.createCluster('Cluster')


  mysql-js> cluster.status()


  mysql-js> cluster.addInstance('root@localhost:3320')


  mysql-js> cluster.status()


 5.获取一个集群


  mysql-js> var cluster = dba.getCluster();

 

 6.重启一个集群

  mysql-js> 


 7.修复集群


  cluster.forceQuorumUsingPartitionOf("root@localhost:3310")


8.重新加入

  cluster.rejoinInstance('root@localhost:3310');


9.解散集群

  cluster.dissolve({force:true})



四、多主模式思考

1.写请求可以分发多个成员上:


MGR多写内部自带冲突解决方式

show VARIABLES like '%auto_increment_offset%';

show VARIABLES like '%auto_increment_increment%';


auto_increment_increment:控制连续列值之间的间隔。

auto_increment_offset:确定AUTO_INCREMENT列值的起点。


MGR默认配置:


GROUP_REPLICATION_AUTO_INCREMENT_INCREMENT

此变量的默认值为'7'。group_replication_auto_increment_increment

的默认值  选择为7,这是一个有效的折衷,同时考虑到每个可能的auto_increment_increment的最大可用值以及正常的组期望大小。


 auto_increment_increment:7(组的大小为3)

auto_increment_offset:server_id(其中M1 = 1,M2 = 2,M3 = 3)


M1:1、8、15、22、29、36…。

M2:2、9、16、23、30、37…。

M3:3、10、17、24、31、38…。


2.DDL发送到一台机子处理


这个本身很难实现,有中间件代理的时候,可以采用将ddl语句同步到一台节点执行。

create

alter

drop