MySQLdocker

docker 搭建 MySQL 主从同步/读写分离(MGR集群架

2021-07-24  本文已影响0人  fanderboy

简介

MySQL Group Replication(简称MGR)字面意思是mysql组复制的意思,但其实他是一个高可用的集群架构,暂时只支持mysql5.7和mysql8.0版本.
优点:

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

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

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

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

1.创建网络,便于容器间的互联

docker network create mysql_group

2.创建三个docker容器

install-mysql-mgr1.sh

#!/bin/bash

echo "======configuration variables======"
container_name=mysql-mgr1
image_name=mysql
version=5.7.26
host_port=3306
container_port=3306
passwrod=123456

echo "======rm container======"
docker stop ${container_name}
docker rm ${container_name}

echo "======run container======"
docker run -itd \
  --name=${container_name} \
  -v /var/lib/${container_name}/conf:/etc/mysql \
  -v /var/lib/${container_name}/data:/var/lib/mysql \
  -v /var/lib/${container_name}/logs:/var/log/mysql \
  -e TZ="Asia/Shanghai" \
  -e MYSQL_ROOT_PASSWORD=${passwrod} \
  --restart=always \
  --network mysql_group \
  --network-alias group1 \
  -p ${host_port}:${container_port} \
  ${image_name}:${version}

install-mysql-mgr2.sh

#!/bin/bash

echo "======configuration variables======"
container_name=mysql-mgr2
image_name=mysql
version=5.7.26
host_port=3307
container_port=3306
passwrod=123456

echo "======rm container======"
docker stop ${container_name}
docker rm ${container_name}

echo "======run container======"
docker run -itd \
  --name=${container_name} \
  -v /var/lib/${container_name}/conf:/etc/mysql \
  -v /var/lib/${container_name}/data:/var/lib/mysql \
  -v /var/lib/${container_name}/logs:/var/log/mysql \
  -e TZ="Asia/Shanghai" \
  -e MYSQL_ROOT_PASSWORD=${passwrod} \
  --network mysql_group \
  --network-alias group2 \
  --restart=always \
  -p ${host_port}:${container_port} \
  ${image_name}:${version}

install-mysql-mgr3.sh

#!/bin/bash

echo "======configuration variables======"
container_name=mysql-mgr3
image_name=mysql
version=5.7.26
host_port=3308
container_port=3306
passwrod=123456

echo "======rm container======"
docker stop ${container_name}
docker rm ${container_name}

echo "======run container======"
docker run -itd \
  --name=${container_name} \
  -v /var/lib/${container_name}/conf:/etc/mysql \
  -v /var/lib/${container_name}/data:/var/lib/mysql \
  -v /var/lib/${container_name}/logs:/var/log/mysql \
  -e MYSQL_ROOT_PASSWORD=${passwrod} \
  --network mysql_group \
  --network-alias group3 \
  --restart=always \
  -p ${host_port}:${container_port} \
  ${image_name}:${version}

3.my.cnf配置文件(每个节点都需配置)

[mysql]
default-character-set = utf8mb4

[mysqld]
#
# General configuration
#
character-set-server = utf8mb4
# server-id必须是唯一的,主节点设置为1,从节点从2-9,此次实验为1主2从
server_id=1
# 服务器禁用TIMESTAMP列非标准行为
explicit_defaults_for_timestamp = ON
# 库表名不敏感,不区分大小写,文件系统以小写保存
lower_case_table_names = 1
# 服务器时区
default-time-zone='+08:00'
# pid
pid-file=/var/run/mysqld/mysqld.pid

#
# Log configuration
#
# 错误日志路径
log_error = /var/log/mysql/mysql.err 
# 将错误信息和告警信息打印到 log 文件
log_error_verbosity = 2
# 启用binlog
log_bin=binlog
# binlog的索引文件名
log_bin_index = binlog.index
# binlog格式
binlog_format=ROW
relay_log = relaylog
relay_log_index = relaylog.index

#############################Group Replication configuration#########################################
#
# Disable other storage engines
#
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

#
# Replication configuration parameters
#
# 开启GTID,必须开启
gtid_mode=ON
# 强制GTID的一致性
enforce_gtid_consistency=ON
# 基于安全的考虑,MGR集群要求复制模式要改成slave记录记录到表中,不然就报错
master_info_repository=TABLE
# 同上配套
relay_log_info_repository=TABLE
# binlog校验规则,5.6之后的高版本是CRC32,低版本都是NONE,但是MGR要求使用NONE
binlog_checksum=NONE
# 因为集群会在故障恢复时互相检查binlog的数据,所以需要记录下集群内其他服务器发过来已经执行过的binlog,按GTID来区分是否执行过.
log_slave_updates=ON

#
# Group Replication configuration
#
# MySQL Server启动时加载相应的插件
plugin_load_add='group_replication.so'
# 记录事务的算法,官网建议设置该参数使用 XXHASH64 算法
transaction_write_set_extraction=XXHASH64
# GROUP的名字,是UUID值,同一个集群内UUID值相同
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
# 是否随服务器启动而自动启动组复制,不建议直接启动,怕故障恢复时有扰乱数据准确性的特殊情况
group_replication_start_on_boot=off
# 每个节点MGR的IP地址和端口,host:port,是MGR的端口,不是数据库的端口
group_replication_local_address= "group1:33061"
# 集群所有MGR的IP地址和端口,是MGR的端口,不是数据库的端口
group_replication_group_seeds= "group1:33061,group2:33061,group3:33061"
# 开启引导模式,添加组成员,用于第一次搭建MGR或重建MGR的时候使用,只需要在集群内的其中一台启动GROUP_REPLICATION时开启,并且在GROUP_REPLICATION启动后关闭
group_replication_bootstrap_group= off
# 默认单主模式
group_replication_single_primary_mode=true
# 单主模式必须设置
group_replication_enforce_update_everywhere_checks=false

注意:
server_id,group_replication_local_address 不同数据库是不同的,其余要保持相同,host后面跟的端口号是自定义的,只要保证和本机的端口不冲突就好,配置好后重启所有容器。

4.配置并启动mgr集群

可参照官方文档:MySQL :: MySQL 5.7 Reference Manual :: 17.2.1.2 Configuring an Instance for Group Replication
进入mysql-mgr1容器
检查是否安装成功:

show plugins;
+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
    .
    .
    .
| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+

开始执行引导

#创建一个用户来做同步的用户,并授权,所有集群内的服务器都需要做
CREATE USER rpl_user@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
#删除所有的binglog日志文件,并将日志索引文件清空,重新开始所有新的日志文件,避免冲突
reset master;
#创建同步规则认证信息,就是刚才授权的那个用户
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery';
#启动引导,注意,只有这台开启引导,其他两台都请忽略这一步
SET GLOBAL group_replication_bootstrap_group=ON;
#启动MGR,所有mysql服务必须都启动
START GROUP_REPLICATION;
#这个时候,就可以先关闭引导了
SET GLOBAL group_replication_bootstrap_group=OFF;

检查组是否已经创建,查询主节点:

SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| group_replication_applier | 622f8534-ec5e-11eb-aa96-0242ac110003 | 6ab96ee01119 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
select variable_value from performance_schema.global_status where variable_name='group_replication_primary_member';
+--------------------------------------+
| variable_value                       |
+--------------------------------------+
| 622f8534-ec5e-11eb-aa96-0242ac110003 |
+--------------------------------------+

另外两台服务器也是照葫芦画瓢 只不过少了引导这一步,直接创建用户,创建规则,start group_replication就可以了.
注意:
如果其中一台出现了故障集群则是会直接提出集群,并不会表现在这张表上
故障数据库重启后,需要登录重新执行start group_replication;此条命令加入集群

上一篇下一篇

猜你喜欢

热点阅读