Linux回顾

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

防火墙

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

1
firewall-cmd -state -start -stop -restart

端口管理

1
2
3
4
5
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镜像

1
2
docker search java
docker pull java

导入导出镜像

1
2
3
4
docker save java > /home/java.tar.gz
docker load < /home/java.tar.gz
docker images
docker rmi java

运行容器

1
2
3
4
5
6
7
8
9
10
11
12
13
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守护进程启动时就已经停止的容器

进入容器

1
2
3
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

暂停、停止容器

1
2
3
4
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镜像

1
2
3
docker pull percona/percona-xtradb-cluster:5.7.21

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

创建内部网络

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

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

创建Docker卷

业务数据保存在宿主机中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 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初始化(数据库初始化比较耗时),如果第一个没有初始化成功,就提前创建了第二个数据库,第二个数据库就会闪退

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[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

部署第二个节点

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

1
2
3
4
5
6
# 第二个节点  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

验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 容器:

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

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

    1
    exit
  4. 停止 PXC 容器:

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

    1
    2
    3
    4
    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镜像

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

配置haproxy

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

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

新建配置文件

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

haproxy.cfg配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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容器

1
2
3
4
5
#在主节点创建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实现双机热备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 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备份需要锁表,只能读

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

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

创建数据卷

1
docker volume create backup

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

1
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,并执行备份

1
2
3
4
5
6
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

1
2
3
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/ 还原