一、基础知识讲解

1 、docker compose build构建镜像

在学习之前,我们需要先了解:docker compose build批量构建镜像的方式

1.1 目录结构

tree -L 3
compose_build/                # 项目根目录 
├── docker-compose.yml        # (239B) 定义了 mynginx 和 mynginx2 两个服务
├── mynginx/                  # 第一个服务的构建上下文
│   └── Dockerfile            #   默认Dockerfile命名,基础 Nginx 构建
└── mynginx2/                 # 第二个服务的构建上下文
    └── dockerfile2           # 自定义Dockerfile命名

小提示:

  1. tree是一个查看目录的好用的linux工具,需要下载;
  2. -L是指定显示层级,后面填入需要显示的最大目录层数;

docker-compose.yml:

services:
  mynginx: #服务1
    image: mytest_build_image:v1.0 指定镜像名称和tag
    build: ./mynginx #指定./mynginx目录下的dockerfile构建镜像

  mynginx2: #服务2
    image: mytest_build_image:v2.0
    build: #指定./mynginx2下的dockerfile2(自定义dockerfile文件)构建镜像
      context: ./mynginx2
      dockerfile: dockerfile2
      args:
        - NGINX_VERSION=latest
  • build:用于docker compose构建镜像
    • context:指定dockerfile文件的路径,默认寻找Dockerfile构建镜像
    • dockerfile:显示指定Dockerfile文件的名称
    • args:配置Dockerfile中arg的参数(Dockerfile中,必须配置有对应的参数)

Dockerfile

FROM nginx:latest
RUN echo "hello hyy_blog" > /usr/share/nginx/html/index.html

dockerfile2

ARG NGINX_VERSION=1.39.1

FROM nginx:${NGINX_VERSION}

RUN echo "hello hyy_blog" > /usr/share/nginx/html/index.html

1.2 构建并查看效果

docker compose build --build-arg NGINX_VERSION=1.27.1

#两个镜像已经构建完成:
docker images *mytest*
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
mytest_build_image   v2.0      a4ed32c9e956   11 minutes ago   188MB
mytest_build_image   v1.0      70ebf586176e   28 minutes ago   161MB

2、MySQL同步方式

2.1 MySQL主从同步架构

在这里插入图片描述

binlog

一种二进制文件,主库发生变化,会把变更记录根据时间顺序写入到这里,后续binlog dump线程会读取这些数据,将其发送给从节点,实现数据同步

binlog dump thread

当从库与主库进行连接时,主库会为每一个从库创建binlog dump thread,负责把binlog中的变更数据同步给从库

IO thread

与主库进行通信,将主库发来的binlog数据传递给relay log

relay log

中继日志,存储从IO thread获取的变更日志,等待被SQL thread 读取并重放

SQL thread

根据relay log中的数据,按顺序重新执行一遍,以确保和主库数据一致(即重放

2.2 MySQL主从同步类型

2.2.1 全同步(数据一致,但性能低)

在这里插入图片描述

  • 同步流程:主结点需要等待从节点落表后,发送ACK,才能把数据返回给客户端;

  • 优点::主从节点数据一致性最强;

  • 缺点::由于需要等待从节点落表并且返回ACK,性能会极大地降低;

2.2.2 异步同步(性能高,但数据一致性差)

MySQL默认采取这种异步同步策略
在这里插入图片描述

  • 流程: 异步同步相比于全同步,只负责把binlog发送给从节点,后续从节点是否接收到不关系,直接返回数据给客户端
  • 优点: 性能比全同步好很多,因为不用等待从节点ACK
  • 缺点: 数据一致性降低
    • 原因: 对于异步同步,主库和从库存在一个更新的时间差,若主库发送binlog之前挂掉,那么后续从库无法获取到原主库的最新信息(binlog没有发过来)
2.2.3 半同步(性能折中,存在幻读问题)

基于传统异步存在的缺陷,mysql 在 5.5 版本推出半同步复制。可以说时异步同步的改进版本

在这里插入图片描述

  • 流程: 主库更新binlog后,保存事务(写入硬盘),同时发送新的binlog给从库,等待从库relaylog成功后的ACK,返回数据给客户端;
  • 优点: 一定程度缓解数据不一致的问题(需要从节点的relaylog成功后的ACK),性能比半同步稍差,但比全同步强很多;
  • 缺点: 性能比异步同步要差,且存在幻读问题
    • 幻读原因: 半同步中,提交存储引擎和发送binlog是并发执行的,可能存在这样一个情况:数据已经存储,但是binlog还没有发送给从结点。别的用户请求主结点时,查询数据已经修改了,但是此时主结点一旦挂掉,由于从节点没有更新binlog数据,从结点充当主结点,别的用户再查询主结点数据数据,发现数据又没了
2.2.4 增强半同步

在这里插入图片描述

  • 流程: 与半同步类似,不过增强半同步在主结点写入binlog和,提交存储引擎发送binlog不在并发执行(避免别的客户督导未同步的数据,进而解决幻读问题),而是等待从节点relaylog ACK后才进行提交存储引擎(硬盘IO);
  • 优点: 相较于半同步,解决了幻读问题的产生;
  • 缺点: 由于提交存储引擎发送binlog不在并发执行,性能相较于半同步会低一些;

2.3 MySQL主从形式

在这里插入图片描述

3、编排搭建MySQL主从集群

3.0 构建目标

单台服务器,搭建一主二从的MySQL集群,定义绑定卷不设置网络(默认bridge网络)

3.1 项目路径

tree -L 2
.
├── docker-compose.yml
├── master
│   ├── Dockerfile-master
│   └── master.sql
└── slave
    ├── Dockerfile-slave
    └── slave.sql

3.2 docker-compose.yml

services:
  mysql-master:
    build:
      context: ./ #指定查看Dockerfile文件的路径./默认是项目当前目录(docker-compose.yml的目录)
      dockerfile: ./master/Dockerfile-master #指定Dockerfile文件名称
    image: mysqlmaster:v1.0 #指定镜像名称:版本
    restart: always 
    container_name: mysql-master
    volumes:
      - ./mastervarlib:/var/lib/mysql #挂载mysql的数据库数据,类型是绑定卷
    ports:
      - 9036:3306
    environment:
      MYSQL_ROOT_PASSWORD: root #指定mysql密码
    
    privileged: true
    # 这里的 command 会让 mysql 启动时直接应用这些配置
    command: ['--server-id=1', #集群中,需要指定每一个mysql实例的id,每个实例id不能相同
              '--log-bin=master-bin', #开启binlog,相当于开启了数据同步
              '--binlog-ignore-db=mysql', # 指定mysql这个数据库不要进行同步,因为这个数据库存储了用户、权限等当前实例的重要信息
              '--binlog_cache_size=256M', # 指定binlog大小
              '--binlog_format=mixed', #binlog日志记录方式为混合模式
              '--lower_case_table_names=1', # 声明数据库表明都是小写
              '--character-set-server=utf8',#字符集指定utf8
              '--collation-server=utf8_general_ci',]

  mysql-slave:
    build:
      context: .
      dockerfile: ./slave/Dockerfile-slave
    image: mysqlslave:v1.0
    restart: always
    container_name: mysql-slave
    volumes: 
      - ./slavevarlib:/var/lib/mysql
    ports:
      - 9037:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
    privileged: true
    command: ['--server-id=2',
              '--log-bin=master-bin',
              '--relay_log=slave-relay', # 开启relay_log,从节点接收主结点binlog日志
              '--lower_case_table_names=1',
              '--character-set-server=utf8',
              '--collation-server=utf8_general_ci',]
    depends_on:
      - mysql-master

  mysql-slave2:
    build:
      context: .
      dockerfile: ./slave/Dockerfile-slave
    image: mysqlslave:v1.0
    container_name: mysql-slave2
    restart: always
    volumes:
      - ./slavevarlib2:/var/lib/mysql
    ports:
      - 9038:3306
    environment:
      - MYSQL_ROOT_PASSWORD=root
    privileged: true
    
    depends_on:
      - mysql-master

关于 binlog_format:
binlog_format 表示记录 binlog 的方式,主要有三种:
1、Row(基于行)—— 生产环境首选/官方默认

  • 原理:不记录 SQL 原文,只记录“具体哪行数据变成了什么样”。例如一条 UPDATE 影响了 1000 行,就记录 1000 行最终的二进制数据变化。
  • 优点绝对精准。无论使用什么复杂或随机函数,主从数据 100% 一致。
  • 缺点日志量巨大。批量改库时极度消耗磁盘空间和网络带宽。

2、Statement(基于语句)

  • 原理:原封不动地记录主库执行过的 SQL 语句。
  • 优点日志极小。节省磁盘 I/O 和带宽,且日志肉眼可读性极强。
  • 缺点易致数据不一致。遇到动态函数(如 NOW()UUID())或触发器时,从库执行的时间点不同,生成的数据就会错乱。

3、Mixed(混合模式)

  • 原理:智能折中方案。平时默认用 Statement 模式省空间,一旦检测到 SQL 中包含 NOW() 等不确定函数,立刻自动切换成 Row 模式记录最终数据。
  • 优点:兼顾了执行效率与数据一致性。
  • 缺点:日志格式频繁动态切换,黑盒感较强,增加了后期排查问题和数据恢复的审计难度。

3.3 master

Dockerfile-master:

FROM mysql:5.7

# 设置时区(软连接,减少空间占用
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 初始化数据库
COPY ./master/master.sql /docker-entrypoint-initdb.d

master.sql:

-- 1. 创建用户(这里不用定义,镜像已经创建好了的)
-- CREATE USER 'root'@'%' IDENTIFIED BY 'root';

-- 2. 授予主从复制相关权限
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'root'@'%';

-- 3. 刷新权限使之立即生效
FLUSH PRIVILEGES;

3.4 slave

Dockerfile-slave:

#和master一样
FROM mysql:5.7

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

COPY ./slave/slave.sql  ./docker-entrypoint-initdb.d

slave.sql:

-- 配置主库的连接信息
CHANGE MASTER TO 
    MASTER_HOST='mysql-master', 
    MASTER_USER='root',
    MASTER_PASSWORD='root',
    MASTER_PORT=3306;

-- 启动从库复制链路
START SLAVE;

3.5 构建镜像/启动服务

docker compose build 
docker compose up -d 
docker ps 
docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                                                    NAMES
c8669ac2eaa1   mysqlslave:v1.0    "docker-entrypoint.s…"   45 minutes ago   Up 45 minutes   33060/tcp, 0.0.0.0:9038->3306/tcp, [::]:9038->3306/tcp   mysql-slave2
f59405cc37f2   mysqlslave:v1.0    "docker-entrypoint.s…"   45 minutes ago   Up 45 minutes   33060/tcp, 0.0.0.0:9037->3306/tcp, [::]:9037->3306/tcp   mysql-slave
16fa37069d45   mysqlmaster:v1.0   "docker-entrypoint.s…"   45 minutes ago   Up 45 minutes   33060/tcp, 0.0.0.0:9036->3306/tcp, [::]:9036->3306/tcp   mysql-master

3.6 查看从属关系

查看主结点状态

docker  exec -it mysql-master bash
bash-4.2# mysql -u root -h 127.0.0.1 -proot

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.44-log MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000005 |      154 |              | mysql            |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

查看从节点状态

docker exec -it mysql-slave bash
bash-4.2# mysql -u root -h 127.0.0.1 -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.44-log MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show slave status;

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: mysql-master < 重点,默认是bridge网络,域名就是主结点容器名:mysql-master
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000005
          Read_Master_Log_Pos: 154
               Relay_Log_File: slave-relay.000010
                Relay_Log_Pos: 369
        Relay_Master_Log_File: master-bin.000005
             Slave_IO_Running: Yes  # <--- 重点
            Slave_SQL_Running: Yes  # <--- 重点
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 739
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0    # <--- 重点
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 7036d065-18fc-11f1-80a0-ce66da72fc8a
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version:


请添加图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐