Docker Compose搭建MySQL主从复制集群

前言

随着应用业务数据不断的增大,应用的 响应速度不断下降,在检测过程中我们不难发现大多数的请求都是 查询操作。此时,我们可以将数据库扩展成 主从复制模式,将 读操作写操作 分离开来,多台数据库 分摊请求,从而 减少单库访问压力,进而应用得到优化。

正文

主从复制的方式

MySQL 5.6 开始主从复制有两种方式:基于日志binlog)和 基于 GTID全局事务标示符)。

本文只涉及基于日志 binlog主从配置

主从复制的流程

MySQL 同步操作通过 3 个线程实现,其基本步骤如下:

  1. 主服务器 将数据的更新记录到 二进制日志Binary log)中,用于记录二进制日志事件,这一步由 主库线程 完成;

  2. 从库主库二进制日志 复制到本地的 中继日志Relay log),这一步由 从库 I/O 线程 完成;

  3. 从库 读取 中继日志 中的 事件,将其重放到数据中,这一步由 从库 SQL 线程 完成。

主从模式的优点

1. 负载均衡

通常情况下,会使用 主服务器 对数据进行 更新删除新建 等操作,而将 查询 工作落到 从库 头上。

2. 异地容灾备份

可以将主服务器上的数据同步到 异地从服务器 上,极大地提高了 数据安全性

3. 高可用

数据库的复制功能实现了 主服务器从服务器间 的数据同步,一旦主服务器出了 故障,从服务器立即担当起主服务器的角色,保障系统持续稳定运作。

4. 高扩展性

主从复制 模式支持 2 种扩展方式:

  • scale-up

向上扩展或者 纵向扩展,主要是提供比现在服务器 性能更好 的服务器,比如 增加 CPU内存 以及 磁盘阵列等,因为有多台服务器,所以可扩展性比单台更大。

  • scale-out

向外扩展或者 横向扩展,是指增加 服务器数量 的扩展,这样主要能分散各个服务器的压力。

主从模式的缺点

1. 成本增加

搭建主从肯定会增加成本,毕竟一台服务器和两台服务器的成本完全不同,另外由于主从必须要开启 二进制日志,所以也会造成额外的 性能消耗

2. 数据延迟

从库主库 复制数据肯定是会有一定的 数据延迟 的。所以当刚插入就出现查询的情况,可能查询不出来。当然如果是插入者自己查询,那么可以直接从 主库 中查询出来,当然这个也是需要用代码来控制的。

3. 写入更慢

主从复制 主要是针对 读远大于写 或者对 数据备份实时性 要求较高的系统中。因为 主服务器 在写中需要更多操作,而且 只有一台 可以写入的 主库,所以写入的压力并不能被分散。

主从复制的前提条件

  1. 主从服务器 操作系统版本位数 一致。

  2. 主数据库和从数据库的 版本 要一致。

  3. 主数据库和从数据库中的 数据 要一致。

  4. 主数据库 开启 二进制日志,主数据库和从数据库的 server_id 在局域网内必须 唯一

具体配置

1. 环境准备

名称版本号
Docker18.03.1-ce
Docker Compose1.21.1
MySQL5.7.17

2. 配置docker-compose.yml

docker-compose.yml

version: '2'
services:
  mysql-master:
    build:
      context: ./
      dockerfile: master/Dockerfile
    environment:
      - "MYSQL_ROOT_PASSWORD=root"
      - "MYSQL_DATABASE=replicas_db"
    links:
      - mysql-slave
    ports:
      - "33065:3306"
    restart: always
    hostname: mysql-master
  mysql-slave:
    build:
      context: ./
      dockerfile: slave/Dockerfile
    environment:
      - "MYSQL_ROOT_PASSWORD=root"
      - "MYSQL_DATABASE=replicas_db"
    ports:
      - "33066:3306"
    restart: always
    hostname: mysql-slave
复制代码

3. 主数据库配置

3.1. 配置Dockerfile

Dockerfile

FROM mysql:5.7.17
MAINTAINER harrison
ADD ./master/my.cnf /etc/mysql/my.cnf
复制代码
3.2. 配置my.cnf文件

my.cnf

[mysqld]
## 设置server_id,一般设置为IP,注意要唯一
server_id=100  
## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql  
## 开启二进制日志功能,可以随便取,最好有含义(关键就是这里了)
log-bin=replicas-mysql-bin  
## 为每个session分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M  
## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed  
## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7  
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
复制代码

4. 从数据库配置

4.1. 配置Dockerfile

Dockerfile

FROM mysql:5.7.17
MAINTAINER harrison
ADD ./slave/my.cnf /etc/mysql/my.cnf
复制代码
4.2. 配置my.cnf文件
[mysqld]
## 设置server_id,一般设置为IP,注意要唯一
server_id=101  
## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql  
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=replicas-mysql-slave1-bin  
## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M  
## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed  
## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7  
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062  
## relay_log配置中继日志
relay_log=replicas-mysql-relay-bin  
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1  
## 防止改变数据(除了特殊的线程)
read_only=1  
复制代码

5. 创建容器

进入 docker 目录,运行 docker-compose 启动命令。

$ docker-compose up -d
复制代码

如图所示,MySQL 主数据库从数据库 的容器创建成功。

分别配置 主数据库从数据库 的连接信息如下:

  • 主数据库

  • 从数据库

6. 配置从数据库

检查从库的起始状态
$ show master status;
复制代码

如图所示,从数据库处于 未同步复制状态

检查主库的状态
$ show master status;
复制代码

记录 主数据库 binary-log文件名称数据同步起始位置

  • File: replicas-mysql-bin.000003
  • Position: 154

从库配置主库信息

从数据库 上运行 主数据库 的相关配置 sql 进行主从关联

CHANGE MASTER TO
    MASTER_HOST='mysql-master',
    MASTER_USER='root',
    MASTER_PASSWORD='root',
    MASTER_LOG_FILE='replicas-mysql-bin.000003',
    MASTER_LOG_POS=154;
复制代码

重新启动 slave 服务

$ stop slave
$ start slave
复制代码

进一步检查 从数据库 的状态信息,两者已经进行 数据同步 关联。

7. 创建目标表

主数据库 中创建一张测试数据表 course

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `lesson_period` double(5,0) DEFAULT NULL,
  `score` double(10,0) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
复制代码

主数据库从数据库 的 数据处于 同步状态,主从复制集群搭建完成。

MySQL的复制类型

基于语句的复制

主服务器上面执行的语句在从服务器上面再执行一遍,在 MySQL-3.23 版本以后支持。

问题:时间上可能不完全同步造成偏差,执行语句的用户也可能是不同一个用户。

基于行的复制

把主服务器上面改变后的内容直接复制过去,而不关心到底改变该内容是由哪条语句引发的,在 MySQL-5.0 版本以后引入。

问题:比如一个工资表中有一万个用户,我们把每个用户的工资+1000,那么基于行的复制则要复制一万行的内容,由此造成的开销比较大,而基于语句的复制仅仅一条语句就可以了。

混合类型的复制

MySQL 默认使用 基于语句的复制,当 基于语句的复制 会引发问题的时候就会使用 基于行的复制MySQL 会自动进行选择。


欢迎关注公众号: 零壹技术栈

本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值