我是基于ChatGPT-turbo-3.5实现的AI助手,在此网站上负责整理和概括文章

本文介绍了Linux系统下Docker的轻量级虚拟机特性及防火墙管理,详细阐述了Docker容器的安装、运行与维护。重点讨论了MySQL单节点的缺点,并比较了PXC和Replication集群方案,展示了PXC的同步复制和高可用性优势。还涉及了HAProxy负载均衡、Keepalived高可用配置以及数据库热备份方法,提供了构建可靠数据库系统的实用指南。

# Linux回顾

Docker创建的所有虚拟实例共用同一个Linux内核,对硬件占用较小,属于轻量级虚拟机

# 防火墙

查看、启动、关闭、重启防火墙

firewall-cmd -state -start -stop -restart

端口管理

firewall-cmd -permanent --add-port=8080-8085/tcp
firewall-cmd -reload
firewall-cmd -permanent-remove-port=8080-8085/tcp
firewall-cmd --list-ports 查看端口
firewall-cmd–permanent–list-services 查看使用网络的程序

# Docker说明

# 安装Java镜像

docker search java
docker pull java

# 导入导出镜像

docker save java > /home/java.tar.gz
docker load < /home/java.tar.gz
docker images
docker rmi java

# 运行容器

docker run -it --name myjava java bash
# 端口映射 -p 宿主机:镜像
docker run -it --name myjava -p 9000:8080 java bash
# 映射文件 -v  --privileged:container内的root拥有真正的root权限。
docker run -it --name myjava -v /home/project/soft --privileged java bash

# 容器自动重启
docker update --restart=always  [container-name]

no 默认值,表示容器退出时,docker不自动重启容器
on-failure 若容器的退出状态非0,则docker自动重启容器,还可以指定重启次数,若超过指定次数未能启动容器则放弃
always 容器退出时总是重启
unless-stopped 容器退出时总是重启,但不考虑Docker守护进程启动时就已经停止的容器

# 进入容器

docker run -itd --name busy --net=net1 --ip 10.0.75.11 -e "DOCKER_GATEWAY=10.0.75.1" busybox

docker exec -it busy sh

# 暂停、停止容器

docker pause myjava
docker unpause myjava
docker stop myjava
docker start -i myjava

# 单节点缺点

大型互联网程序用户群体庞大,所以架构必须要特殊设计
单节点的数据库无法满足性能上的要求
单节点的数据库没有冗余设计,无法满足高可用

# Mysql集群方案

  1. PXC 集群方案:
    • 所有节点都是可读可写的,PXC 同步机制是同步进行的,它能保证数据强一致性
  2. Replication集群方案:
    • Replication从节点不能写入,主从同步是单向的,无法从slave节点向master点同步
    • Replication同步机制是异步进行的,它如果从节点停止同步,依然可以向主节点插入数据,正确返回,造成数据主从数据的不一致性。
  3. PXC 是用牺牲性能保证数据的一致性,Replication在性能上是高于PXC的。所以两者用途也不一致。
    • PXC是用于重要信息的存储,例如:订单、用户信息等。
    • Replication用于一般信息的存储,能够容忍数据丢失,例如:购物车,用户行为日志等。

# PXC (Percona XtraDB Cluster)

PXC是针对MySQL用户的高可用性和扩展性解决方案,基于Percona Server(MySQL改进版,性能提升很大) 。

Percona Server 是MySQL的改进版本,使用 XtraDB 存储引擎,在功能和性能上较 MySQL 有着很显著的提升,如提升了在高负载情况下的 InnoDB 的性能,为 DBA 提供了一些非常有用的性能诊断工具,另外有更多的参数和命令来控制服务器行为。

# PXC的作用

  • 同步复制,事务可以在所有节点上提交。
  • 多主机复制,你可以写到任何节点。
  • 从( slave)服务器上的并行应用事件,真正的“并行复制”。
  • 自动节点配置。
  • 数据一致性,不再有未同步的从服务器

# PXC集群的注意事项

  • 尽可能的控制PXC集群的规模,节点越多,数据同步速度越慢
  • 所有 PXC节点的硬件配置要一致,如果不一致,配置低的节点将拖慢数据同步速度
  • PXC集群只支持InnoDB引擎,不支持其他的存储引擎

# 安装PXC镜像

docker pull percona/percona-xtradb-cluster:5.7.21

docker load < /home/soft/pxc.tar.gz

# 创建内部网络

处于安全考虑,需要给PXC集群实例创建Docker内部网络 docker内置网段172.17.0.*

# 创建网段
docker network create --subnet=10.0.75.1/24 net1
docker network inspect net1
docker network rm net1

# 创建Docker卷

业务数据保存在宿主机中

# pxc无法映射目录,只能创建数据卷,分别创建mysql数据卷和配置卷
# docker volume rm mysql-data
# docker volume rm mysql-conf
docker volume create mysql-data
docker volume create mysql-conf

# 可以去挂载的配置卷去修改my.cnf 
[root@centos7 ~]# docker inspect mysql-conf
[
    {
        "CreatedAt": "2023-06-15T21:46:38+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/mysql-conf/_data",
        "Name": "mysql-conf",
        "Options": null,
        "Scope": "local"
    }
]

docker volume create --name v1
docker volume create --name v2
docker volume create --name v3
docker volume create --name v4
docker volume create --name v5

# 创建PXC容器

只需要向PXC镜像传入运行参数就能创建出PXC容器
注意:要等待前一个docker镜像中的mysql初始化(数据库初始化比较耗时),如果第一个没有初始化成功,就提前创建了第二个数据库,第二个数据库就会闪退

[root@centos7 ~]# docker rm $(docker ps -a -q) -f


# 第一个节点 -v mysql-data:/var/lib/mysql  -v mysql-conf:/etc/mysql
docker run -d -p 4406:3306  \
-e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=abc123456 \
-e CLUSTER_NAME=PXC -e EXTRABACKUP_PASSWROD=abc123456 \
-v v1:/var/lib/mysql \
--privileged --name=mysql-node1  \
--net=net1 --ip 10.0.75.11 percona/percona-xtradb-cluster:5.7.21

# 查看日志
docker logs -f  mysql-node1

# 使用docker ps命令可以看到容器已经启动成功,使用navicat等工具连接 如果连接成功就表示第一个节点已经成功启动

# 到/var/lib/docker/volumes/mysql-conf_data下面的my.cnf更改配置文件,然后重新启动容器
vim /var/lib/docker/volumes/mysql-conf/_data/my.cnf
docker restart mysql-node1

# 启动成功后连接到服务器上执行命令查看是否修改成功
select @@GLOBAL.sql_mode
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

# 部署第二个节点

跟第一台服务器一样,创建两个数据卷,然后直接启动容器

# 第二个节点  docker rm mysql-node2 -f
docker run -d -p 4407:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=mysql-node1 --privileged -v v2:/var/lib/mysql --name=mysql-node2 --net=net1 --ip 10.0.75.12 percona/percona-xtradb-cluster:5.7.21

#  docker logs mysql-node2
# docker exec -it  mysql-node2 bash

# 验证

create database test DEFAULT CHARSET=utf8;

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8

insert user (name) values("zs1");
select * from user;

# 注意: 在 PXC 集群中使用了多个节点,并且使用了 HAProxy 进行负载均衡。由于每个节点都管理自己的自增计数器,因此在多个节点上插入数据时,自增 ID 可能会在节点之间不连续。
# 解决此问题的一种方法是在每个表上禁用自增 ID 的使用,而是使用应用程序生成的 UUID 或另一个唯一标识符作为记录主键。这将确保您的应用程序在任何节点上插入记录时都能保持唯一性。

# 并发写入的时候,负载均衡把请求分发给不同的pxc节点。A节点写入记录使用了主键值1,没来得及提交事务的时候。B节点写入记录发现主键值1没人使用,所以用了主键值1。这时候A节点提交事务,通知B节点,主键值1我已经用了。B节点回复A节点,主键1我在使用,所以两个节点都放弃主键1,继续用下一个主键值尝试写入记录,所以主键值就不连续了。正确的做法是用程序生成主键值,放弃数据库主键自增长

# 停止启动pxc

使用 docker stop <container_name> 命令时没有正确停止 PXC 服务,可能会导致数据文件损坏或丢失

  1. 进入正在运行的 PXC 容器:

    docker exec -it <container_name> bash
    docker exec -it mysql-node1 bash
    docker exec -it mysql-node2 bash
  2. 在容器中运行以下命令停止 PXC 服务:

    docker exec -it mysql-node1 service mysql stop
    docker exec -it mysql-node2 service mysql stop
  3. 退出容器:

    exit
  4. 停止 PXC 容器:

    docker stop mysql-node1
    docker stop mysql-node2
  5. 启动

    docker start mysql-node1
    docker exec -it mysql-node1 service mysql start
    
    docker start mysql-node2
    docker exec -it mysql-node2 service mysql start

# 使用haproxy进行负载均衡

如果单纯是想做pxc集群的话上面的步骤已经完成,但是想要使用负载均衡来使用pxc集群的话,我们可以使用haproxy工具

# 拉取haproxy镜像

#拉取haprox镜像 haproxytech/haproxy-ubuntu
docker pull haproxytech/haproxy-ubuntu

# 配置haproxy

在任一节点(mysql-node1,mysql-node2)上执行下面命令进入容器

docker exec -it mysql-node1 bash
# 进入容器后执行:
mysql -uroot -p
# 输入上面设置的密码 后执行:
create user 'haproxy'@'%' identified by '';

# 新建配置文件

#新建目录
mkdir -p /data/haproxy
#新建配置文件
vi /data/haproxy/haproxy.cfg

haproxy.cfg配置

global
    #工作目录,这边要和创建容器指定的目录对应
    # chroot /usr/local/etc/haproxy
    #日志文件
    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_monitor
    #统计报告格式
    stats realm Global\ statistics
    #登陆帐户信息
    stats auth admin:admin
    #数据库负载均衡
    listen proxy-mysql
    #访问的IP和端口,haproxy开发的端口为3306
    #假如有人访问haproxy的3306端口,则将请求转发给下面的数据库实例
    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 10.0.75.11:3306 check weight 1 maxconn 2000
    server MySQL_2 10.0.75.12:3306 check weight 1 maxconn 2000
    #使用keepalive检测死链
    option tcpka

# 启动haproxy容器

#在主节点创建haproxy容器 docker rm -f ha01
docker run -d --restart=always -p 8888:8888 -p 3307:3306 -v /data/haproxy:/usr/local/etc/haproxy \
--name ha01  --net=net1 -e "DOCKER_GATEWAY=10.0.75.1" --privileged haproxy

# docker restart ha01

# 验证是否启动成功

输入地址 http://192.168.61.10:8888/dbs_monitor admin/admin

如果出现如下图两个节点都是绿色状态则说明连接成功,两个节点都是正常的状态

测试连接

# 高可用

单节点Haproxy不具备高可用,必须要有冗余设计。

使用Keepalived实现双机热备

# exit是退出容器界面 ctrl+D 退出容器
docker exec -u root -it ha01 bash
# 将系统的镜像更换为国内的镜像源
cp /etc/apt/sources.list /etc/apt/sources.list.bak

echo "
deb https://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse

deb https://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse

deb https://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
" > /etc/apt/sources.list
#更新镜像源
apt-get update
#安装keepalived
apt-get install keepalived
#安装vim
apt-get install vim

yum install keepalived
Keepalived的配置文件是/etc/keepalived/keepalived.conf
最后一步 service keepalived start

# 热备份数据

mysqldump属于冷备份

冷备份是关闭数据库时候的备份方式,通常做法是拷贝数据文件

冷备份是最简单最安全的一种备份方式

大型网站无法做到关闭业务备份数据,所以冷备份不是最佳选择

冷备份是关闭数据库时候的备份方式,通常做法是拷贝数据文件

冷备份是最简单最安全的一种备份方式

大型网站无法做到关闭业务备份数据,所以冷备份不是最佳选择

热备份是在系统运行的状态下备份数据,也是难度最大的备份

MySQL常见的热备份有LVM和XtraBackup两种方案

建议使用XtraBackup热备MySQL

  • XtraBackup备份过程不锁表、快速可靠
  • XtraBackup备份过程不会打断正在执行的事务
  • XtraBackup能够基于压缩等功能节约磁盘空间和流量

LVM备份需要锁表,只能读

全量备份是备份全部数据。备份过程时间长,占用空间大

增量备份是只备份变化的那部分数据。

创建数据卷

docker volume create backup

然后映射backup数据卷,因为是先删除之前的节点,这个时候要关联node2节点

 docker run -d -p 4406:3306 -v v1:/f/skillTrain -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v backup:/f/data -e CLUSTER_JOIN=node2 --privileged --name=node1 --net=net1 --ip 10.0.75.2 pxc

PXC容器中安装XtraBackup,并执行备份

dcoer exec -it node1 bash
apt-get update
apt-get install percona-xtrabackup-24
innobackupex --user=root --password=abc123456 /data/backup/full
查看数据卷在哪
docker inspect backup

数据库可以热备份,但是不能热还原,只能冷回复。为了避免恢复过程中的数据同步,我们采用空白的MySQL还原数据,然后再建立PXC集群

还原数据前要将未提交的事务回滚,还原数据之后重启MySQL

rm -rf /var/lib/mysql/*
innobackupex --user=root --password=abc123456 --apply-back /data/backup/full/2018/04-15105-09-07/ 回滚
innobackupex --user=root --password=abc123456 --copy-back /data/backup/full/2018/04-15105-09-07/ 还原
更新于

请我喝[茶]~( ̄▽ ̄)~*

Fulsun 微信支付

微信支付

Fulsun 支付宝

支付宝