Docker 搭建 MySql PXC集群踩坑记录
文章目录
- MYSQL 集群方案介绍
- 1 单节点数据库的弊病
- 2 单节点 MYSQL 的性能瓶颈
- 3 常见 MYSQL 集群方案
- PXC 原理
- PXC 方案与 Replication 方案的对比
- PXC 的数据强一致性
- 4 创建 MySql 集群
- 4.1. 拉取pxc镜像:
- 4.2. 创建内部网络
- 4.3. 创建Docker 卷
- 创建 PXC 容器
- 测试
MYSQL 集群方案介绍
1 单节点数据库的弊病
- 大型互联网程序用户群体庞大,所以架构必须要特殊设计
- 单节点的数据库无法满足性能上的要求
- 单节点的数据库没有冗余设计,无法满足高可用
如:高校教务系统查询考试成绩,很多人同时查询数据库
2 单节点 MYSQL 的性能瓶颈
3 常见 MYSQL 集群方案
PXC 原理
Percona XtraDB Cluster(下文简称PXC集群)提供了MySQL高可用的一种实现方法。PXC集群以节点组成(推荐至少3节点,便于故障恢复,后面会讨论两节点的情况),每个节点都是基于常规的 MySQL/Percona Server,意味着你可以从集群中分离出某节点单独使用。集群中每个节点都包含完整的数据。
PXC 方案与 Replication 方案的对比
PXC 的数据强一致性
- 同步复制,事务在所有集群节点要么同时提交,要么不提交 Replication
- 采用异步复制,无法保证数据的一致性
异步复制无法保证数据一致性的坏处:如在淘宝下单且支付完成,但是却找不到订单
4 创建 MySql 集群
踩众坑后吐血总结:
- 拉镜像不要拉最新的,不然可能会出现容器闪退之类的问题,建议5.7.20
从节点启动之后闪退
情况一
一种情况是由于主节点还没有启动,就启动了从节点,那这个时候从节点肯定是闪退的。所以需要先启动主节点,再启动从节点。
情况二
第二种情况,是由于PXC在退出的时候会给集群中最后退出的那台打上标记,当集群重新启动的时候需要先启动最后关闭的那台节点机器。
但是docker中容器启动是没有办法更改指令的,所以需要修改数据卷中grastate.data文件,把safe_to_bootstrap参数改为0。PXC中就是讲最后关闭的节点的safe_to_bootstrap标记为1,需要按照主节点启动。
由于PXC的公司在制作Linux的镜像的时候,默认是不会给子节点退出的safe_to_bootstrap配置打上1的,所以真正要修改的是主节点的safe_to_bootstrap,主节点修改为1,才可以真正的启动,启动之后再去启动从节点。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IdwrAurO-1606187624944)(images/20200816224927309.png)]
所以建议直接最后关闭主节点
主节点启动之后闪退
情况一
当主节点突然宕机,从节点都正常运行,这时候主节点不能按照主节点启动。这时候需要删除主节点的容器,检查数据卷上的safe_to_bootstrap是否为0,如果不是则改为0。然后以从节点的方式创建容器,加入集群。可以使用任何PXC节点,然后从节点加入PXC集群
情况二
需要修改主节点的safe_to_bootstrap为1
4.1. 拉取pxc镜像:
$ docker pull percona/percona-xtradb-cluster:5.7.20
$ docker tag percona/percona-xtradb-cluster:5.7.20 percona-xtradb-cluster:5.7.20
4.2. 创建内部网络
出于安全考虑,需要给 PXC 集群实例创建 Docker 内部网络
#创建网段,假设创建网段172.18.0.0(默认:172.17.0.0),子网掩码是24位
$ docker network create --subnet=172.18.0.0/24 net1
#查看网段
$ docker network inspect net1
# 删除网段,这里不需要删除
$ docker network inspect net1
4.3. 创建Docker 卷
Docker 卷是容器中的 PXC 节点映射数据目录的解決办法
- 一旦创建出docker容器,尽量不要把业务数据存在容器内,因为出问题的话数据可能就找不到了。
- 可以把业务数据保存在宿主机内,通过映射技术将宿主机上的目录映射到容器内。在运行容器的时候,把业务数据保存在映射目录里,也就是存储到宿主机上面。如果容器出什么问题,可以在创建一个容器,再将目录映射给该容器,则业务数据就导入了。
# 创建volume
$ docker volume create v1
# 查看volume
$ docker volume inspect v1
# 删除volume
$ docker volume rm v1
docker volume create v1
docker volume create v2
docker volume create v3
docker volume create v4
docker volume create v5
4. 创建 PXC 容器
◆只需要向 PXC 镜像传入运行参数就能创建出 PXC 容器
命令 | 说明 |
---|---|
-d | 代表创建的容器在后台运行 |
-p | 端口映射 宿主机端口:容器端口 |
-v | 路径映射 |
-e MYSQL_ROOT_PASSWORD=abc123456 | 指定mysql的root账号密码为abc123456 |
-e CLUSTER_NAME=PXC | 执行名称为PXC |
-e XTRABACKUP_PASSWORD=abc123456 | 指定mysql数据同步时用的密码为abc123456 |
–privileged | 给最高的权限 |
–name=node1 | 节点名称node1 |
–net=net1 | 使用的内部网段 |
–ip 172.18.0.2 | 分发的ip地址 |
percona-xtradb-cluster:5.7.20 | 镜像名称 |
第一个主节点
#容器的3306,映射到宿主机的3307
docker run -d -p 3307:3306 -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 --privileged --name=node1 --net=net1 --ip 172.18.0.2 percona-xtradb-cluster:5.7.20
切记因第一个节点初始化比较耗时一定要等第一个容器创建成功可以使用MySQL客户端连接了才能创建第二个,或者会报错创建不了下面的容器!
密码自己改一下,但是基本上我试过的,-e配置的MYSQL_ROOT_PASSWORD 可能没用,在docker里面登录不进去。(之前一直只能启动一个节点有可能就是这里的问题)
登录docker的node1镜像里面登录mysql:
xiyucai@xiyucais-MacBook-Pro ~ % docker exec -it node1 /bin/sh
# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
#...
mysql> update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost';
Query OK, 0 rows affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 1
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
mysql> quit;
创建其它从节点
切记,第一个节点的mysql初始化会很慢,在它没有初始化完成前不要开启其它node,不然这些node会闪退的
docker run -d -p 3308:3306 -v v2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node1 —privileged —name=node2 —net=net1 —ip 172.18.0.3 percona-xtradb-cluster:5.7.20
docker run -d -p 3309:3306 -v v3:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node1 —privileged —name=node3 —net=net1 —ip 172.18.0.4 percona-xtradb-cluster:5.7.20
docker run -d -p 3310:3306 -v v4:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node1 —privileged —name=node4 —net=net1 —ip 172.18.0.5 percona-xtradb-cluster:5.7.20
docker run -d -p 3311:3306 -v v5:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=node1 —privileged —name=node5 —net=net1 —ip 172.18.0.6 percona-xtradb-cluster:5.7.20
5. 测试
在任意节点内新建数据库,并插入数据
CREATE TABLE `student` (
`id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
查看其它节点是否更新数据
如果其它节点没有自动更新就刷新数据库,注意不是flush
- 如果数据同步成功,则大功告成!
参考1
参考2
参考3
还没有评论,来说两句吧...