Docker Compose搭建MySQL主从复制集群

前言

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

正文

主从复制的方式

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

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

主从复制的流程

MySQL 同步操做经过 3 个线程实现,其基本步骤以下:数据库

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

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

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

主从模式的优势

1. 负载均衡

一般状况下,会使用 主服务器 对数据进行 更新删除新建 等操做,而将 查询 工做落到 从库 头上。安全

2. 异地容灾备份

能够将主服务器上的数据同步到 异地从服务器 上,极大地提升了 数据安全性bash

3. 高可用

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

4. 高扩展性

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

  • scale-up

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

  • scale-out

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

主从模式的缺点

1. 成本增长

搭建主从确定会增长成本,毕竟一台服务器和两台服务器的成本彻底不一样,另外因为主从必需要开启 二进制日志,因此也会形成额外的 性能消耗

2. 数据延迟

从库主库 复制数据确定是会有必定的 数据延迟 的。因此当刚插入就出现查询的状况,可能查询不出来。固然若是是插入者本身查询,那么能够直接从 主库 中查询出来,固然这个也是须要用代码来控制的。

3. 写入更慢

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

主从复制的前提条件

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

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

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

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

具体配置

1. 环境准备

名称 版本号
Docker 18.03.1-ce
Docker Compose 1.21.1
MySQL 5.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 会自动进行选择。


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

零壹技术栈

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

相关文章
相关标签/搜索