[Docker] MySQL集群负载热备

820 阅读6分钟

前景

我的小骚年~还记得大学抢课时的巨卡巨辣鸡的网站吗~是的~回忆总想哭。就是因为单节点的数据库,承载着学校几万人的请求量,因此很有必要做数据库的负载均衡。

集群方案


Replication

???

PXC强一致性解决方案

1、同步复制,事务在所有集群节点上要么同时提交,要么不提交

2、多主复制,可以在任意一个节点写入

3、数据同步的强一致性,所有节点数据保持一致

4、尽可能的控制PXC集群的规模,集群节点越多,数据同步速度越慢,见下图

5、所有pxc节点的硬件配置要相同,集群数据同步速度取决于最低配置的节点

6、pxc集群只支持Innodb引擎,其他引擎如MyISAM是不会同步到其他节点的


PXC集群安装

开放端口介绍

3306 - MySQL服务端口

4444 - 请求全量同步(SST)端口 [ 全量同步会限制其他节点的写入操作,拖慢数据查询速度 ]

4567 - 集群节点通信端口

4568 - 请求增量同步(IST)端口

下载PXC镜像( 版本号一定要一致~)

# 拉取镜像
docker pull percona/percona-xtradb-cluster:5.7.21
# 镜像改名
docker tag percona/percona-xtradb-cluster:5.7.21 pxc
docker rmi percona/percona-xtradb-cluster:5.7.21

创建内部网络

docker network create --subnet=172.22.0.0/24 pxc-net
# 如果出现如下错误,说明该网段已被占用,可执行docker network ls查看
Error response from daemon: Pool overlaps with other one on this address space

创建Docker卷(数据目录映射)

docker volume create v1
# 查看创建的卷
docker inspect v1
[
    {
        "CreatedAt": "2019-08-26T16:45:16+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/v1/_data",
        "Name": "v1",
        "Options": {},
        "Scope": "local"
    }
]

启动PXC容器( node1容器启动需要时间初始化~所以node2需要等待完成后启动 )

docker run -d  
-p 3306:3306
-v v1:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=abc123456
-e CLUSTER_NAME=PXC
-e XTRABACKUP_PASSWORD=abc123456
--privileged
--name=node1
--net=pxc-net
--ip 172.22.0.2

docker run -d -p 3307:3306 -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 --privileged --name=node1 --net=pxc-net --ip 172.22.0.2 pxc
docker run -d -p 3308:3306 -v v2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 --privileged --name=node2 --net=pxc-net --ip 172.22.0.3 pxc
docker run -d -p 3309:3306 -v v3:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 --privileged --name=node3 --net=pxc-net --ip 172.22.0.4 pxc

-d 后台运行容器 -p 容器与本机端口映射 -v 容器与本机数据目录映射 -e PXC的配置参数 --net 指定网段 --ip 分配指定网段下的固定IP  --privileged 赋予容器文件最高操作权限  --name 设置容器名称 

数据库负载均衡

完成上面步骤后,MySQL的集群也就搭建好了,接下来的问题就是我们的应用如果在程序里没实现负载均衡,都把请求转发到node1,而且还肩负着同步的任务,辣么这个压力就会非常之大,所以下一步我们就需要做数据库的负载均衡 - Haproxy中间件。

1、下载镜像

docker pull haproxy

2、创建haproxy配置文件( /etc/haproxy/haproxy.cfg )

global
	#工作目录
	chroot /usr/local/etc/haproxy
	#日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info
	log 127.0.0.1 local5 info
	#守护进程运行
	daemon

defaults
	log	global
	mode	http
	#日志格式
	option	httplog
	#日志中不记录负载均衡的心跳检测记录
	option	dontlognull
        #连接超时(毫秒)
	timeout connect 5000
        #客户端超时(毫秒)
	timeout client  50000
	#服务器超时(毫秒)
        timeout server  50000

#监控界面	
listen  admin_stats
	#监控界面的访问的IP和端口
	bind  0.0.0.0:8888
	#访问协议
        mode        http
	#URI相对地址
        stats uri   /dbs
	#统计报告格式
        stats realm     Global\ statistics
	#登陆帐户信息
        stats auth  admin:abc123456
#数据库负载均衡
listen  proxy-mysql
	#访问的IP和端口
	bind  0.0.0.0:3306  
        #网络协议
	mode  tcp
	#负载均衡算法(轮询算法)
	#轮询算法:roundrobin
	#权重算法:static-rr
	#最少连接算法:leastconn
	#请求源IP算法:source 
        balance  roundrobin
	#日志格式
        option  tcplog
	#在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测
        option  mysql-check user haproxy
        server  MySQL_1 172.22.0.2:3306 check weight 1 maxconn 2000  
        server  MySQL_2 172.22.0.3:3306 check weight 1 maxconn 2000  
	server  MySQL_3 172.22.0.4:3306 check weight 1 maxconn 2000 
	#使用keepalive检测死链
        option  tcpka  

3、启动Haproxy容器

docker run -it -d -p 4001:8888 -p 4002:3306 -v /etc/haproxy:/usr/local/etc/haproxy --name h1 --privileged --net=pxc-net --ip 172.22.0.5 haproxy

docker exec -it h1 haproxy -f /usr/local/etc/haproxy/haproxy.cfg

4、创建haproxy用户

CREATE USER 'haproxy'@'%' IDENTIFIED by '';

5、打开MYSQL集群监听界面

http://192.168.184.134:4001/dbs

6、应用如何使用haproxy

url: 192.168.184.134:4002
user: root
password: abc123456

haproxy采用轮询算法将请求均匀分发到mysql实例上。

双机热备[高可用]?

单节点Haproxy无法实现高可用,多节点Haproxy想要实现高可用还需要在容器内使用keepalive抢占同一个虚拟IP,keepalive之间相互心跳检测实现高可用。

1、进入到haproxy容器终端

docker exec -it h1 bash
apt-get update
apt-get install keepalived

2、配置keepalived

apt-get install vim
vim /etc/keepalived/keepalived.conf
####################################
vrrp_instance  VI_1 {
    state  MASTER     # 主服务器
    interface  eth0   # 网卡设备
    virtual_router_id  51  # 虚拟路由ID
    priority  100    # 权重
    advert_int  1    # 每隔几秒心跳
    authentication {   # keepalived之间的相互检测安全识别机制
        auth_type  PASS
        auth_pass  123456
    }
    virtual_ipaddress {  # 虚拟IP列表
        172.22.0.201
    }
}
###################################

3、启动

service keepalived start


热备份数据

LVM是基于Linux分区备份,可以备份任何数据库的数据,缺点就是备份时会锁表~           XTraBackUp热备份则不需要锁表。

1、创建数据卷【用于备份的数据目录】

docker volume create backup
# 查看数据卷
docker inspect backup
[
    {
        "CreatedAt": "2019-08-28T09:09:25+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/backup/_data",
        "Name": "backup",
        "Options": {},
        "Scope": "local"
    }
]

2、停止且删除pxc节点node1

docker stop node1
docker rm node1

3、创建且启动pxc容器

docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql -v backup:/data --privileged -e CLUSTER_JOIN=node2 --name=node1 --net=pxc-net --ip 172.22.0.2 pxc

-v backup:/data  备份的数据卷映射;-e CLUSTER_JOIN=node2 重新加入到集群中;

4、pxc容器node1安装xtrabackup

docker exec -it node1 bash
apt-get update
apt-get install percona-xtrabackup-24

5、全量备份

首次备份需要全量备份,之后每天可以执行增量备份,可选择周期性全量备份。因全量备份受限于数据量和计算机性能,不可能每天执行全量备份~

innobackupex --user=root --password=abc123456 /data/backup/full 

恢复备份

???

集群状态信息

SHOW STATUS LIKE 'wsrep%';


wsrep_incoming_addresses 集群里的所有节点ip、port

wsrep_last_applied 同步应用次数

wsrep_last_committed 事务提交次数

wsrep_replicated 被其他节点复制的总数

wsrep_received 从其他节点收到的写入总数