MySQL高级讲座篇之:如何利用`Docker`和`Compose`快速搭建一个MySQL集群?

各位观众老爷,大家好!今天咱们不聊风花雪月,就来点硬核的——用 Docker 和 Compose 快速搭建 MySQL 集群。保证让你们听完,感觉自己也能瞬间变身 DBA!

一、为啥要用 Docker 和 Compose 整 MySQL 集群?

传统的 MySQL 集群搭建,那叫一个酸爽!各种配置、各种依赖,搞不好折腾个几天几夜才能搞定。而且,环境还容易出问题,比如版本冲突、配置不对等等。

但是!有了 Docker 和 Compose,这一切都变得 So Easy!

  • 隔离性好: 每个 MySQL 实例都运行在独立的 Docker 容器里,互不干扰。
  • 环境一致: 不管你在 Windows、Mac 还是 Linux 上,只要有 Docker,环境就一样。告别“在我电脑上能跑”的魔咒!
  • 快速部署: 一条 docker-compose up 命令,整个集群就起来了。
  • 易于扩展: 想加几个节点?改改 Compose 文件,再执行一条命令就搞定。
  • 方便管理: Docker 提供了一整套管理工具,监控、日志、重启都很方便。

二、集群架构:选哪个姿势最舒服?

MySQL 集群有很多种架构,比如主从复制、主主复制、Galera 集群等等。为了简单易懂,咱们先从最经典的主从复制开始。

  • 主从复制(Master-Slave Replication):

    • 一个主节点(Master)负责写操作。
    • 多个从节点(Slave)负责读操作。
    • 主节点的数据会自动同步到从节点。
    • 优点: 读写分离,提高性能;备份方便;容错性好。
    • 缺点: 主节点挂了,需要手动切换;数据可能存在延迟。

    咱们先搞定这个,后续可以再深入研究其他的架构。

三、手把手教你搭集群:代码说话!

  1. 准备 Docker 和 Docker Compose

    这个我就不细说了,网上教程一大堆,自行安装。确保你的 Docker 版本 >= 1.13 和 Docker Compose 版本 >= 1.6。

    可以用 docker -vdocker-compose -v 命令查看版本。

  2. 创建 Docker Compose 文件(docker-compose.yml

    这是整个集群的核心!所有的配置都在这里。

    version: "3.9"
    services:
      mysql-master:
        image: mysql:8.0
        container_name: mysql-master
        ports:
          - "3306:3306"
        environment:
          MYSQL_ROOT_PASSWORD: root_password
          MYSQL_REPLICATION_USER: repl
          MYSQL_REPLICATION_PASSWORD: repl_password
        volumes:
          - mysql_master_data:/var/lib/mysql
          - ./master.cnf:/etc/mysql/conf.d/master.cnf
        networks:
          - mysql-network
    
      mysql-slave1:
        image: mysql:8.0
        container_name: mysql-slave1
        ports:
          - "3307:3306"
        environment:
          MYSQL_ROOT_PASSWORD: root_password
          MYSQL_REPLICATION_USER: repl
          MYSQL_REPLICATION_PASSWORD: repl_password
        volumes:
          - mysql_slave1_data:/var/lib/mysql
          - ./slave.cnf:/etc/mysql/conf.d/slave.cnf
        depends_on:
          - mysql-master
        networks:
          - mysql-network
    
      mysql-slave2:
        image: mysql:8.0
        container_name: mysql-slave2
        ports:
          - "3308:3306"
        environment:
          MYSQL_ROOT_PASSWORD: root_password
          MYSQL_REPLICATION_USER: repl
          MYSQL_REPLICATION_PASSWORD: repl_password
        volumes:
          - mysql_slave2_data:/var/lib/mysql
          - ./slave.cnf:/etc/mysql/conf.d/slave.cnf
        depends_on:
          - mysql-master
        networks:
          - mysql-network
    
    volumes:
      mysql_master_data:
      mysql_slave1_data:
      mysql_slave2_data:
    
    networks:
      mysql-network:
        driver: bridge
    • version: "3.9" 指定 Compose 文件的版本。
    • services 定义要运行的服务(也就是 MySQL 实例)。
    • mysql-mastermysql-slave1mysql-slave2 每个服务的名称。
    • image: mysql:8.0 使用 MySQL 8.0 的 Docker 镜像。
    • container_name 容器的名称。
    • ports 端口映射,将容器的 3306 端口映射到宿主机的 3306、3307、3308 端口。
    • environment 设置环境变量,包括 root 密码、复制用户的用户名和密码。
    • volumes 数据卷,用于持久化存储 MySQL 的数据。
    • depends_on 定义服务之间的依赖关系,确保主节点先启动。
    • networks 定义网络,让所有容器都在同一个网络里,可以互相访问。
  3. 创建 MySQL 配置文件

    我们需要为主节点和从节点分别创建配置文件。

    master.cnf (主节点配置)

    [mysqld]
    server-id=1
    log_bin=mysql-bin
    binlog_format=ROW
    enforce_gtid_consistency=ON
    gtid_mode=ON
    relay_log_recovery = 1
    • server-id 每个 MySQL 实例必须有一个唯一的 ID。
    • log_bin 启用二进制日志,这是主从复制的基础。
    • binlog_format 设置二进制日志的格式为 ROW,这是推荐的格式,可以避免一些复制问题。
    • enforce_gtid_consistency 启用 GTID 一致性,GTID 可以更好地跟踪事务,保证数据一致性。
    • gtid_mode 开启 GTID 模式。
    • relay_log_recovery 开启 relay log 恢复。

    slave.cnf (从节点配置)

    [mysqld]
    server-id=2
    relay_log_recovery = 1
    • server-id 从节点的 server-id,要和主节点不一样。
    • relay_log_recovery 开启 relay log 恢复。

    注意: 这两个配置文件要放在和 docker-compose.yml 同一个目录下。

  4. 启动集群

    docker-compose.yml 所在的目录下,执行以下命令:

    docker-compose up -d
    • docker-compose up:启动 Compose 文件中定义的所有服务。
    • -d:以后台模式运行。

    稍等片刻,集群就启动完成了。可以用 docker ps 命令查看容器的运行状态。

  5. 配置主从复制

    接下来,我们需要登录到主节点和从节点,配置主从复制关系。

    (1) 登录主节点

    docker exec -it mysql-master bash
    mysql -u root -p'root_password'

    (2) 创建复制用户并授权

    CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_password';
    GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
    FLUSH PRIVILEGES;

    (3) 获取主节点的状态

    SHOW MASTER STATUS;

    记录下 FilePosition 的值,稍后会用到。

    (4) 退出主节点

    exit
    exit

    (5) 登录从节点

    docker exec -it mysql-slave1 bash
    mysql -u root -p'root_password'

    (6) 配置从节点连接主节点

    CHANGE MASTER TO
        MASTER_HOST='mysql-master',
        MASTER_USER='repl',
        MASTER_PASSWORD='repl_password',
        MASTER_LOG_FILE='mysql-bin.000001', -- 替换成 SHOW MASTER STATUS 得到的 File 值
        MASTER_LOG_POS=4; -- 替换成 SHOW MASTER STATUS 得到的 Position 值

    (7) 启动从节点复制

    START SLAVE;

    (8) 检查复制状态

    SHOW SLAVE STATUSG

    如果 Slave_IO_RunningSlave_SQL_Running 都显示 Yes,就说明复制成功了!

    (9) 退出从节点

    exit
    exit

    重复步骤 (5) 到 (9),配置 mysql-slave2 注意修改 MASTER_LOG_FILEMASTER_LOG_POS 为对应主节点的值。

  6. 验证复制

    在主节点上创建一个数据库和表,然后插入一些数据,看看从节点是否能同步到。

    (1) 登录主节点

    docker exec -it mysql-master bash
    mysql -u root -p'root_password'

    (2) 创建数据库和表

    CREATE DATABASE test_db;
    USE test_db;
    CREATE TABLE test_table (
        id INT PRIMARY KEY AUTO_INCREMENT,
        name VARCHAR(255)
    );
    INSERT INTO test_table (name) VALUES ('Hello'), ('World');

    (3) 退出主节点

    exit
    exit

    (4) 登录从节点

    docker exec -it mysql-slave1 bash
    mysql -u root -p'root_password'

    (5) 检查数据

    USE test_db;
    SELECT * FROM test_table;

    如果能看到主节点插入的数据,就说明复制成功了!

    mysql-slave2 上也执行相同的操作,验证数据是否同步。

四、进阶玩法:更多骚操作!

  1. 使用环境变量配置 MySQL

    可以将 MySQL 的配置信息,比如 root 密码、复制用户等等,都放在环境变量里,这样可以避免把敏感信息写在 Compose 文件里。

    version: "3.9"
    services:
      mysql-master:
        image: mysql:8.0
        container_name: mysql-master
        ports:
          - "3306:3306"
        environment:
          MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
          MYSQL_REPLICATION_USER: ${MYSQL_REPLICATION_USER}
          MYSQL_REPLICATION_PASSWORD: ${MYSQL_REPLICATION_PASSWORD}
        volumes:
          - mysql_master_data:/var/lib/mysql
          - ./master.cnf:/etc/mysql/conf.d/master.cnf
        networks:
          - mysql-network

    然后在运行 docker-compose up 命令之前,先设置环境变量:

    export MYSQL_ROOT_PASSWORD=my_secret_password
    export MYSQL_REPLICATION_USER=repl
    export MYSQL_REPLICATION_PASSWORD=repl_password
    docker-compose up -d
  2. 使用 Dockerfile 定制 MySQL 镜像

    如果你需要安装一些额外的 MySQL 插件,或者修改一些默认配置,可以使用 Dockerfile 来定制 MySQL 镜像。

    FROM mysql:8.0
    # 安装一些额外的插件
    RUN apt-get update && apt-get install -y --no-install-recommends some-package
    # 复制自定义配置文件
    COPY my.cnf /etc/mysql/conf.d/my.cnf

    然后在 Compose 文件中使用定制的镜像:

    version: "3.9"
    services:
      mysql-master:
        build: .  # Dockerfile 所在的目录
        container_name: mysql-master
        ports:
          - "3306:3306"
        environment:
          MYSQL_ROOT_PASSWORD: root_password
          MYSQL_REPLICATION_USER: repl
          MYSQL_REPLICATION_PASSWORD: repl_password
        volumes:
          - mysql_master_data:/var/lib/mysql
          - ./master.cnf:/etc/mysql/conf.d/master.cnf
        networks:
          - mysql-network
  3. 使用 Docker Compose Scale 扩展集群

    如果你的读请求量很大,可以增加从节点的数量。使用 docker-compose scale 命令可以快速扩展集群。

    docker-compose scale mysql-slave=5

    这条命令会将从节点的数量扩展到 5 个。当然,你需要手动配置新增的从节点。

五、常见问题和注意事项

  1. 数据持久化: Docker 容器默认是不持久化存储数据的,所以一定要使用数据卷(Volumes)来存储 MySQL 的数据,否则容器重启后数据会丢失。
  2. 网络配置: 确保所有的容器都在同一个网络里,这样才能互相访问。
  3. 端口冲突: 如果宿主机上已经占用了 3306 端口,需要修改 Compose 文件中的端口映射。
  4. 主从复制延迟: 主从复制可能会存在延迟,这是正常的。延迟的大小取决于网络状况、数据量等等。
  5. 安全性: 生产环境一定要设置复杂的密码,并限制访问权限。
  6. 监控: 使用 Docker 的监控工具或者第三方监控工具,监控 MySQL 集群的运行状态。

六、总结

今天我们学习了如何使用 Docker 和 Compose 快速搭建 MySQL 主从复制集群。通过 Docker 和 Compose,我们可以轻松地管理 MySQL 集群,提高开发效率,降低运维成本。

希望今天的讲座能帮助大家更好地理解和使用 Docker 和 Compose。记住,实践是检验真理的唯一标准!赶紧动手试试吧!

最后,祝大家早日成为 MySQL 大佬!下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注