基于docker-compose的MySQL主从复制集群

前言

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

正文

1 主从复制的方式

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

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

2 主从复制的流程

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

  1. 主服务器 将数据的更新记录到 二进制日志Binary log)中,用于记录二进制日志事件,这一步由 主库线程 完成;
  2. 从库 将 主库 的 二进制日志 复制到本地的 中继日志Relay log),这一步由 从库I/O线程 完成;
  3. 从库 读取 中继日志 中的 事件,将其重放到数据中,这一步由 从库SQL线程 完成。

3 主从模式的优点

1)负载均衡

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

2)异地容灾备份

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

3)高可用

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

4)高扩展性

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

  • scale-up

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

  • scale-out

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

4 主从模式的缺点

1)成本增加

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

2)数据延迟

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

3)写入更慢

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

5 主从复制的前提条件

  1. 主从服务器 操作系统版本 和 位数 一致。
  2. 主数据库和从数据库的 版本 要一致。
  3. 主数据库和从数据库中的 数据 要一致。
  4. 主数据库 开启 二进制日志,主数据库和从数据库的 server_id 在局域网内必须 唯一

6 配置文件

docker --version
Docker version 18.09.0, build 4d60db4
docker-compose --version
docker-compose version 1.25.1, build a82fef07
mysql version 
5.7

目录结构如图所示:

6.1 配置docker-compose.yml

version: '3'
services:
  mysql-master:
    image: mysql:5.7
    environment:
      - "MYSQL_ROOT_PASSWORD=root"
      - "MYSQL_DATABASE=replicas_db"
    volumes:
      - /home/istorm/mysql_test/master/my.cnf:/etc/mysql/my.cnf
      - /home/istorm/mysql_test/master/mysql_data_master:/var/lib/mysql
    links:
      - mysql-slave1
      - mysql-slave2
    ports:
      - "33065:3306"
    restart: always
    hostname: mysql-master
    container_name: mysql-master

  mysql-slave1:
    image: mysql:5.7
    environment:
      - "MYSQL_ROOT_PASSWORD=root"
      - "MYSQL_DATABASE=replicas_db"
    volumes:
      - /home/istorm/mysql_test/slave1/my.cnf:/etc/mysql/my.cnf
      - /home/istorm/mysql_test/slave1/mysql_data_slave:/var/lib/mysql
    ports:
      - "33066:3306"
    restart: always
    hostname: mysql-slave1
    container_name: mysql-slave1

  mysql-slave2:
    image: mysql:5.7
    environment:
      - "MYSQL_ROOT_PASSWORD=root"
      - "MYSQL_DATABASE=replicas_db"
    volumes:
      - /home/istorm/mysql_test/slave2/my.cnf:/etc/mysql/my.cnf
      - /home/istorm/mysql_test/slave2/mysql_data_slave:/var/lib/mysql
    ports:
      - "33067:3306"
    restart: always
    hostname: mysql-slave2
    container_name: mysql-slave2

6.2 主数据库配置配置

my.cnf文件

[mysqld]
## 设置server_id,一般设置为IP,注意要唯一
server_id=100    # 三个my.cnf配置文件中的id均不相同
## 复制过滤:也就是指定哪个数据库不用同步(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

6.3 slave1从数据库配置

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

6.4 slave1从数据库配置

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

6.5 slave2从数据库配置

my.cnf文件

[mysqld]
## 设置server_id,一般设置为IP,注意要唯一
server_id=102
## 复制过滤:也就是指定哪个数据库不用同步(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

6.6 运行docker-compose

在docker-compose.yml文件所在目录下运行

docker-compose up -d

7 配置从数据库

检查从库的起始状态

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

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

CREATE TABLE IF NOT EXISTS `runoob_tbl`(
`runoob_id` INT UNSIGNED AUTO_INCREMENT,
`runoob_title` VARCHAR(100) NOT NULL,
`runoob_author` VARCHAR(40) NOT NULL,
`submission_date` DATE,
PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO runoob_tbl  (runoob_title, runoob_author, submission_date) VALUES ("study python", "test1", NOW());
INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES ("study MySQL", "test2", NOW());
INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES ("study JAVA", "test3", '2016-05-06');

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Docker Compose是一个用于定义和运行多容器Docker应用程序的工具。Redis是一个开源的内存数据结构存储系统,支持多种数据结构,如字符串、哈希、列表等。Redis主从复制是一种数据复制机制,用于将一个Redis服务器的数据复制到其他Redis服务器上。 下面是一个使用Docker Compose配置Redis主从复制的示例: 1. 首先,创建一个名为docker-compose.yml的文件,并在其中定义两个Redis服务,一个作为主服务器,另一个作为从服务器。示例配置如下: ```yaml version: '3' services: redis-master: image: redis ports: - "6379:6379" volumes: - ./redis-master-data:/data command: redis-server --appendonly yes redis-slave: image: redis volumes: - ./redis-slave-data:/data command: redis-server --slaveof redis-master 6379 ``` 2. 在上述配置中,我们定义了两个服务:redis-master和redis-slave。redis-master服务使用Redis官方镜像,并将主服务器的6379端口映射到主机的6379端口。同时,我们将主服务器的数据目录挂载到本地的redis-master-data目录。 3. redis-slave服务也使用Redis官方镜像,并将从服务器的数据目录挂载到本地的redis-slave-data目录。在command字段中,我们使用--slaveof参数指定redis-slave作为redis-master的从服务器,并指定主服务器的地址和端口。 4. 在终端中,进入包含docker-compose.yml文件的目录,并运行以下命令启动Redis主从复制: ```bash docker-compose up -d ``` 5. 等待一段时间,直到两个Redis服务器都成功启动。您可以使用以下命令检查容器的状态: ```bash docker-compose ps ``` 6. 现在,您可以通过连接到主服务器的6379端口来访问Redis主服务器,并将数据复制到从服务器。您可以使用以下命令连接到Redis服务器: ```bash redis-cli -h localhost -p 6379 ``` 7. 在连接到主服务器后,可以执行一些Redis命令来设置和检索数据。这些数据将自动复制到从服务器。 这就是使用Docker Compose配置Redis主从复制的基本步骤。您可以根据需要进行调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值