Docker搭建MySQL读写分离主从模式 & 分布式数据库中间件Mycat分库分表应用

筅森魡賤 提交于 2020-04-12 20:08:09

系统环境:Ubuntu 18.04.4 Docker 19.03.6

一、MySQL读写分离主从模式

1. 下载镜像
docker pull mysql
当前最新版本:mysql Ver 8.0.19 for Linux on x86_64 (MySQL Community Server - GPL)
2. 启动主节点并修改配置文件
docker run -it --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql bash
修改/etc/mysql/my.cnf配置文件(还得先apt update更新软件包列表才能安装vim等编辑工具,比较繁琐,所以可以选择先配置好my.cnf文件再docker run -v 挂载进容器)
配置文件 my.cnf 修改如下:

[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql

# 以上是原有默认配置,add variables如下:
# 在同一个Master-Slave集群里不能有重复id
server-id       = 3306
# 不配置默认3306
# port		= 3306
# 二进制日志文件存储路径及名称(在docker容器内涉及到权限问题,所以直接写在datadir下)
log-bin         = /var/lib/mysql/binlog
# 需要开启binlog的数据库,多个则配置多行binlog-do-db
binlog-do-db    = training
# binlog-do-db	= db2
# binlog-do-db	= db3
# 密码认证方式(加密方式) MySQL 8.0+ 默认是caching_sha2_password
# 如果需要直接连接可以如下改回老版本的mysql_native_password或者create user时identified with mysql_native_password by <passwd>针对单个用户
# default_authentication_plugin	= mysql_native_password

注:修改完配置文件后需要重启mysql才能生效,一般命令是systemctl restart mysqld,但是在docker容器中没有权限执行systemctl命令,所以选择退出容器后 docker restart <container>

docker exec -it mysql bash
mysql -uroot -p [-hx.x.x.x -P3306]
# 创建用户, @'ip'可以用@'%',不限IP
create user 'replica'@'x.x.x.x' identified by '123456';
# 赋予复制权限
GRANT REPLICATION SLAVE ON *.* to 'replica'@'x.x.x.x';
FLUSH PRIVILEGES;
# 查看主机状态
show master status;


记下File和Position两个参数值在从库连接主库时将用到

  1. 从节点配置
# 容器内依然使用3306端口,免去修改端口的麻烦,宿主机端口使用3307
docker run -it --name mysql_3307 -p 3307:3306 -e MYSQL_ROOT_PASSWORD mysql bash

从节点my.cnf配置主要修改server-id不同,不需要log-bin和binlog-do-db参数

[mysqld]
server-id       = 3307
# 容器内端口
# port		= 3306
# 读写分离,从库只读(0: 读写,1: 只读)
read_only	= 1
# 限制super用户,read_only只限制普通用户写操作
super_read_only	= 1

重启容器后生效

Ctrl+P+Q 快捷键
docker restart mysql_3307
docker exec -it mysql_3307
mysql -uroot -p123456	# 如果容器内也使用3307端口,需跟上参数 -P3307

stop slave;
# 连接主机	CHANGE MASTER TO option [, option] ...
change master to master_host='xxx.xxx.xxx.xx',
master_port=3306,
master_user='replica',
master_password='123456',
# 这两个参数要跟上述截图master status的参数值一致
master_log_file='binlog.000010',
master_log_pos=155,
# 默认使用caching_sha2_password加密方式时添加如下参数
get_master_public_key=1,
# 或者使用master_public_key_path指定主机公钥文件
master_public_key_path='/etc/mysql/master_rsa_public.key';

# 启动slave进程
# 查看从机状态
show slave status\G

至此主从复制配置完成,Slave_IO_Running和Slave_SQL_Running都为Yes说明开启主从同步成功,
否则可以查看Slave_SQL_Running_State状态查看失败原因,或者没有没有执行start slave;


change master的更多参数可见官网:https://dev.mysql.com/doc/refman/8.0/en/change-master-to.html
关于主机公钥文件获取:
进入master后show variables like "%caching_sha2_password%";
可以看到Caching_sha2_password_rsa_public_key或者key_path: public_key.pem,这个文件路径:/var/lib/mysql/public_key.pem
拷贝--BEGIN……END--这部分内容到从服务器,可以新建文件/etc/mysql/master_rsa_public.key写入。
change master时master_public_key_path='/etc/mysql/master_rsa_public.key'参数指定 ;
客户端登录时mysql -uroot -p --server-public-key-path=/etc/mysql/master_rsa_public.key指定

  1. 备份主库已有数据 完成上述步骤后,后续对主机的写操作才会同步到从机,开启同步前主机已有数据并不会同步,需要备份后导入从库,再开启主从同步。
    (1)备份前锁定主库,只允许读不允许写,防止备份过程中、开启主从同步前有新数据插入
mysql> show global variables like "%read_only%";
mysql> set global read_only=1;
mysql> set global super_read_only=1	# 限制super用户写操作
# 如果当前不是super用户,需要限制super用户写操作就执行给所有表加读锁命令,但是当前连接不能退出,否则就自动释放锁了
mysql> flush tables with read lock;

(2)备份主库
mysqldump语法:

备份命令: docker exec mysql /usr/bin/mysqldump -uroot -p123456 training > mysql_master_backup.sql
注:对于警告不要在命令行输入密码的问题,可以先在/etc/mysql/my.cn添加配置:

[mysqldump]
user		= root
password	= 123456

然后执行docker exec mysql mysqldump training > mysql_master_backup.sql
(3)将备份数据导入从库
注:需要在从库中建立好同名数据库才能将数据导入从库
mysql> create database training;
同理在从库的my.cnf中添加配置:

[mysql]
user		= root
password	= 123456

导入数据: cat mysql_master_backup.sql | docker exec -i mysql_3307 /usr/bin/mysql training
(4)开启主从同步
也就是上面2、 3点的步骤了,最好是在锁表前先配置好,只留最后 change master 和 start slave 到这里执行,以减少锁表的时间。
change master 注意修改 master_log_file 和 master_log_pos 的值与 master status 的值一致。
(5)释放主库的锁

mysql> unlock tables;
mysql> set global read_only=0;
mysql> set global super_read_only=0;
mysql> show global variables like "%read_only%";

注:线上环境要注意尽量减少锁表的时间和锁表的范围!

mysql> show full processlist; 可以看到:
至此读写分离的主从架构就搭建完成了,但不会自动进行主备切换,自动切换需要第三方工具配合,如:
Keepalived 与MySQL互为主从自动切换配置
MHA 实现MySQL主从自动切换 高可用 (Master High Availability)

对于配置文件错误无法启动容器的情况可以先把配置文件复制出来修改好再复制回去:

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
docker cp mysql_3307:/etc/mysql/my.cnf ./my.cnf
docker cp ./my.cnf mysql_3307:/etc/mysql/my.cnf

端口开放情况排查:

  • 能否ping通
  • netstat -apt 端口监听状态
  • telnet ip port 能否远程连接
  • ECS 安全规则配置
  • 防火墙(ufw)
  • iptables (iptables -I INPUT -p tcp --dport 3308 -j ACCEPT)

二、分布式数据库中间件Mycat分库分表简单应用

  1. Mycat 安装
    Mycat 官网 查找所需版本下载链接
# 下载
wget http://dl.mycat.io/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz Mycat-server-1.6.7.4-release-linux.tar.gz
# 解压至 /etc/,会自动创建 mycat 目录
tar -zxvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /etc


conf目录下有三个主要的配置文件:

  • server.xml Mycat系统配置信息,包括账号密码、权限、端口等参数
  • scheme.xml Mycat的逻辑库、表、分片规则、DataNode以及DataSource
  • rule.xml 表拆分规则定义

待续……

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!