1. 程式人生 > >Docker Compose搭建mysql主從複製

Docker Compose搭建mysql主從複製

系統環境

  • docker 1.12.3
  • mysql5.7.17
  • deepin 15.3桌面版(這個沒啥影響,因為我們用docker)

要點說明

  • 使用docker bridge網路,設定靜態IP
  • 使用volumes掛載,不使用資料卷容器(因為我使用docker compose沒搞成功 - -!)
  • 映象使用build建立(保留擴充套件性),不使用image
  • 目前為止,沒有暴露埠號,只是兩個slavelink了master.馬上著手研究使用mycat完成mysql的主從複製+讀寫分離,敬請期待.
  • 掛載hosts檔案,以便於使用hostname代替ip地址

Begin

docker-engine
安裝

docker-compose安裝

拉取mysql:5.7.17映象


docker pull mysql:5.7.17

需要掛載的配置檔案

目錄結構

直接上圖:目錄結構

簡要說明
  • mysql-master: 存放master配置檔案
  • mysql-s1: 存放第一個slave配置檔案
  • mysql-s2: 存放第二個slave配置檔案
  • hosts: 本地路由

mysql-master的配置

沒多少東西,只有一個mysqld.cnf需要在末尾追加:

  #表名不區分大小寫
  lower_case_table_names=1
  #給資料庫服務的唯一標識,一般為大家設定伺服器Ip的末尾號
server-id=2 log-bin=master-bin log-bin-index=master-bin.index

mysql-s1/mysql-s2的配置

跟master一樣,也只有一個mysqld.cnf需要在末尾追加:

  server-id=3 #第一個用3,第二個用4
  log-bin=s1-bin.log #第一個用s1-bin.log,第二個用s2-bin.log
  sync_binlog=1
  lower_case_table_names=1

hosts檔案配置

127.0.0.1   localhost
172.18.0.2  m1
172.18.0.3  s1
172.18.0.4  s2

docker-compose配置檔案和Dockerfile

目錄結構

直接上圖:目錄結構

Dockerfile

其實master s1 s2的Dockerfile都是一致的,咱就是為了保持一定的擴充套件性才這麼寫的.
我們完全可以用docker-composeimage代替.

在docker-compose.yml中image和build不能一起使用的

好吧,看一下這個Dockerfile

FROM mysql:5.7.17
MAINTAINER <ssab work_wjj@163.com>
EXPOSE 3306
CMD ["mysqld"]
docker-compose.yml

好吧,重點來了.

version: '2' # 這個version是指dockerfile解析時用的版本,不是給我們自己定義版本號用的.
services:
  m1: # master
    build: ./master # ./master檔案下需要有Dockerfile檔案,並且build屬性和image屬性不能一起使用
    container_name: m1 # 容器名
    volumes: # 掛載 下邊每行前邊的`-`代表這個東西是陣列的一個元素.就是說volumes屬性的值是一個數組
      - /home/ssab/config/mysql-master/:/etc/mysql/:ro # 注意改下對映關係
      - /etc/localtime:/etc/localtime:ro
      - /home/ssab/config/hosts:/etc/hosts:ro # 注意改下對映關係
    networks: # 網路
      mysql: # 見跟services平級的networks,在最下邊
        ipv4_address: 172.18.0.2 # 設定靜態ipv4的地址
    ulimits: # 作業系統限制
      nproc: 65535
    hostname: m1 # hostname
    mem_limit: 1024m # 最大記憶體使用不超過1024m,我在本地機器上測試,才只寫了1024m,生產上需要根據自己的伺服器配置,以及docker容器數進行調優.
    restart: always # 容器重啟策略
    environment: # 設定環境變數
      MYSQL_ROOT_PASSWORD: m1test
  s1: # slave1
      build: ./s1
      container_name: s1
      volumes:
        - /home/ssab/config/mysql-s1/:/etc/mysql/:ro
        - /etc/localtime:/etc/localtime:ro
        - /home/ssab/config/hosts:/etc/hosts:ro
      networks:
        mysql:
          ipv4_address: 172.18.0.3
      links:
        - m1
      ulimits:
        nproc: 65535
      hostname: s1
      mem_limit: 1024m
      restart: always
      environment:
        MYSQL_ROOT_PASSWORD: s1test
  s2:# slave2
    build: ./s2
    container_name: s2
    volumes:
      - /home/ssab/config/mysql-s2/:/etc/mysql/:ro
      - /etc/localtime:/etc/localtime:ro
      - /home/ssab/config/hosts:/etc/hosts:ro
    links:
      - m1
    networks:
      mysql:
        ipv4_address: 172.18.0.4
    ulimits:
      nproc: 65535
    hostname: s2
    mem_limit: 1024m
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: s2test
networks: # docker網路設定
  mysql: # 自定義網路名稱
    driver: bridge # 橋接
    ipam: # 要使用靜態ip必須使用ipam外掛
      driver: default
      config:
      - subnet: 172.18.0.0/24
        gateway: 172.18.0.1

run

docker-compose.yml檔案的目錄下執行

  docker-compose up -d

別激動,我們現在才只是完成了一半….

設定mysql主從複製.

配置master

  • 進入master的mysql命令列
docker exec -it m1 /bin/bash
  mysql -u root -p

輸入MYSQL_ROOT_PASSWORD:的值m1test,進入mysql命令列模式.

  • 建立用於主從複製的使用者repl

    mysql> create user repl;
  • repl使用者授予slave的許可權

    
    #repl使用者必須具有REPLICATION SLAVE許可權,除此之外沒有必要新增不必要的許可權,密碼為repl。說明一下172.18.0.%,這個配置是指明repl使用者所在伺服器,這裡%是萬用字元,表示172.18.0.0-172.18.0.255的Server都可以以repl使用者登陸主伺服器。當然你也可以指定固定Ip。
    
    mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.18.0.%' IDENTIFIED BY 'repl';
  • 鎖庫,不讓資料再進行寫入動作,這個命令在結束終端會話的時候會自動解鎖

    FLUSH TABLES WITH READ LOCK;
  • 檢視master狀態

    mysql> show master status;

    顯示如下:

    +-------------------+----------+--------------+------------------+-------------------+
    | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +-------------------+----------+--------------+------------------+-------------------+
    | master-bin.000003 |      636 |              |                  |                   |
    +-------------------+----------+--------------+------------------+-------------------+
    1 row in set (0.00 sec)

    記下master-bin.000003636一會在slave用.

配置slave1

  • 進入s1的mysql命令列
docker exec -it s1 /bin/bash
  mysql -u root -p

輸入MYSQL_ROOT_PASSWORD:的值s1test,進入mysql命令列模式.

  • 連線master

    mysql> change master to master_host='m1',master_port=3306,master_user='repl',master_password='repl',master_log_file='master-bin.000003',master_log_pos=636;
  • 啟動slave

    mysql> start salve;

配置slave2

幾乎跟slave一致….咱就不寫了…

實驗

好了,到此位置,配置已經完成,那是否成功了捏…
我們來試一下.

測試master寫入後是否能夠同步到slave

  • 在master的mysql命令列下建立資料庫:ms-test

    mysql> create database mstest;
  • 去兩臺slave上檢視是否也有了mstest資料庫.

    mysql> show databases;

    如果顯示如下:

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mstest             |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    5 rows in set (0.00 sec)

    則證明成功.

咱還可以建立一個表,插入一條資料試試

自己來吧,哈哈哈.

總結

通過以上步驟,咱們搭建了一個以docker-compose管理的mysql master-slave模式的主從複製.
下一步,我們需要進行暴露埠,或者使用links屬性來讓應用或者其他客戶端工具能夠訪問我們的mysql.
再下一步,我們需要使用mycat中介軟體來完成我們的讀寫分離.

共同努力,一起進步!