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 會自動進行選擇。


歡迎關注公衆號: 零壹技術棧

零壹技術棧

本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。

相關文章
相關標籤/搜索