基于Docker搭建数据库集群

828 阅读3分钟

主从复制的原理

随着业务量越来越大,单机架构无法满足I/O访问需求,为了提升数据库性能,我们会将数据库操作进行读写分离,写操作在主库(Master)完成,读操作在从库(Slave)完成。

如上图所示,主从复制的大致流程为:

  1. 主库(Master)的更新操作被写到 binlog;
  2. 从库(Slave)执行 start slave 命令启动 I/O Thread 和 SQL Thread进程;
  3. 从库(Slave)的 I/O Thread 会与主库(Master)建立长连接,主库会有一个线程专门维护连接,便于将增量 binlog 发送给从库;
  4. 从库(Slave)读取主库(Master)传过来的 binlog 内容,并写入到 Relay Log(中转日志);
  5. 从库(Slave)的 SQL Thread 会读取 Relay Log,将更新内容写到数据库中。

主从数据库搭建

docker-composer.yml 如下:

version: '3'
services:
  mysql-master:
    image: mysql:5.7
    container_name: mysql-master
    command: --server_id=1 --log-bin=mysql-bin --gtid_mode=ON --enforce_gtid_consistency=ON
    environment:
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - ~/data/mysql-master:/var/lib/mysql
    ports:
      - "33061:3306"

  mysql-slave:
    image: mysql:5.7
    container_name: mysql-slave
    command: --server_id=2 --log-bin=mysql-bin --gtid_mode=ON --enforce_gtid_consistency=ON
    environment:
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - ~/data/mysql-slave:/var/lib/mysql
    ports:
      - "33062:3306"

networks:
  default:
    driver: bridge

这里简单配置了一主一从,主从数据库要求 id 不一致,这里把主库 id 设置为1,从库 id 设置为2,运行 docker-compose up -d 命令,启动两个数据库服务。

注:一定要开启 binlog,主从复制的实现依赖于 binlog 日志。

配置主从同步

这里基于 GTID 协议配置主从关系,MySQL 5.6起推荐采用这种方式。

  • 进入 mysql-master 数据库,运行以下命令,创建一个用于主从复制的用户。

    CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
    
  • 进入 mysql-slave 数据库,运行 change master 命令配置要同步的主库信息。

    CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='slave', MASTER_PASSWORD='123456', MASTER_AUTO_POSITION=1;
    
  • 运行 show slave status\G; 查看从库状态。

  • 运行 start slave; 命令,启动 I/O线程SQL线程

  • 通过 ROOT 用户登录到 mysql-slave ,运行 set global read_only=ON; 将从库设置为只读模式。

主备关系的建立

主备关系和主从关系的建立是一样的,同时也在主库上运行 change master 命令,我们把这种主库和备库互为主备关系的架构叫做双 M 架构。需要注意的是:主/备库上需要将 log_slave_updates 配置项设置为 ON ,这样在备库同步数据之后也能生成对应的 binlog,为切换为主库做准备,保证集群的高可用性。

验证主从数据同步

在主库中新建一个 test 数据库和 一个 test 数据表,并插入几条数据:

进入从库,查看刚刚数据是否已经同步过来:

数据已经都同步到从库当中,主从复制架构搭建完成。

主从延迟优化

从库同步主库的数据需要经过几个步骤:主库将更新写入 binlog、从库写入中转日志、从库SQL线程读取中转日志执行更新,这几个步骤都有延迟,延迟是不可避免的,只能优化,影响延迟的因素主要是以下几方面:

  1. 主库、从库服务器配置不一样,配置越差,延迟时间越长;
  2. 业务读操作较多,导致从库压力大;
  3. 有大事务执行操作,事务耗时较长,从库同步时也需要耗费较长时间;
  4. 主从之间网络延迟大,或者从库根据 binlog 日志进行数据同步时间长。

相应的优化方案如下:

  1. 对服务器进行升级,控制延迟到合理范围;
  2. 增加从库数量;
  3. 大事务操作尽量安排在业务低峰期执行;
  4. 对于实时性要求高的场景,可以将读写操作强制走主库;实时性要求不高的场景,可以通过 Ajax 或 JavaScript 在前端 UI 交互上倒计时若干秒后跳转,或者让用户主动点击按钮进行跳转,变相延迟读取从库的时间点。