1. 程式人生 > >Docker搭建MySQL主從叢集

Docker搭建MySQL主從叢集

        關於MySQL主從模式,如果我們直接在本機上搭建的話,是沒法搭建的,只能藉助於虛擬機器,但有的時候我們又需要搭建一個主從叢集,以便於進行一些功能性的測試。這個時候我們就可以嘗試使用docker,藉助於docker的容器化技術,我們只需要建立兩個MySQL容器,並且佔用主機的兩個埠即可,對主機沒有其他額外的影響。這種方式非常的輕量,而且也容易複製。本文則主要講解如何通過docker來搭建MySQL叢集。

1. 環境準備

        在搭建主從叢集之前,我們需要在本機上安裝一個docker伺服器,具體的安裝步驟讀者可參見docker的官網https://www.docker.com/

下載服務安裝。安裝完成之後,執行如下命令能正常顯示則說明安裝成功了:

$ docker --version
Docker version 18.09.0, build 4d60db4

2. 主從叢集搭建

2.1 master伺服器準備

        在安裝完docker之後,我們首先執行如下命令執行一個master容器:

docker run --name mysql-master --privileged=true -v /home/mysql/master-data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d xiaochunping/mysql-master

        在執行上述命令之後,docker首先會檢測本地有沒有目標映象,即xiaochunping/mysql-master,如果沒有,則會下載該映象,然後根據配置的引數執行該映象。上述命令中各個引數的含義如下:

  • --name指定執行之後的容器的名稱為mysql-master
  • --privileged指定了當前容器是否真正的具有root許可權,所謂的root許可權是指具有宿主機的root許可權,而不僅僅只是在容器內部有root許可權;
  • -v指定了容器中指定目錄掛載到宿主機上的某個目錄,這樣做的目的在於防止容器中配置的資料丟失,因為docker容器在重啟之後是不會保留前一次在其內部執行的相關資料的;
  • -p表示宿主機上的某個埠對映到docker容器內的某個埠,這裡也就是將宿主機的3306埠對映到容器內部的3306埠;
  • -e表示指定當前容器執行的環境變數,該變數一般在容器內部程式的配置檔案中使用,而在外部執行容器指定該引數。這裡的MYSQL_ROOT_PASSWORD表示容器內部的MySQL的啟動密碼;
  • -d引數指定了當前容器是在後臺執行。

        在master容器啟動完成之後,我們通過docker ps命令即可看到這個執行的容器:

CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                                            NAMES
fa4afaeb24c4        xiaochunping/mysql-master   "docker-entrypoint.s…"   12 days ago         Up About an hour    0.0.0.0:3306->3306/tcp                           mysql-master

        可以看到,master容器已經正常啟動了,然後我們需要進入到該容器內部,對master節點進行一定的配置。可以通過如下命令進入該容器:

# 通過容器id方式,這裡的id就是上面docker ps中展示的id
docker exec -it fa4afaeb24c4 /bin/bash
# 通過容器名稱方式,這裡的名稱就是建立容器時指定的名稱,也就是mysql-master
docker exec -it mysql-master /bin/bash

        進入容器後,我們需要連線其MySQL服務:

# 這裡的密碼就是最開始建立容器時指定的密碼
mysql -uroot -proot

        然後我們需要為從伺服器建立一個可以用來master伺服器的賬戶,也就是建立一個專門用來複制binlog的賬號,並且賦予該賬號複製許可權,其命令如下:

grant replication slave on *.* to 'test'@'%' identified by '123456';
flush privileges;

        這裡的grant replication slave是一個命令格式,表示賦予後面的賬戶以複製的許可權,這樣slave節點就能夠獲取到master節點對資料的更新。上述命令中建立的賬戶的使用者名稱為test,密碼為123456。接著我們需要檢視master節點的binlog狀態:

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000014 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

        這裡需要記住這個File和Position屬性的值,因為下面在配置slave的時候需要用到。

2.2 slave伺服器準備

        對於從容器的使用,其啟動命令與master容器非常相似,但也有一些小小的區別:

docker run --name mysql-slave --privileged=true -v /home/mysql/slave-data:/var/lib/mysql -p 3307:3306 --link mysql-master:master -e MYSQL_ROOT_PASSWORD=root -d xiaochunping/mysql-slave

        從容器啟動與主容器啟動引數主要有一下兩點:

  • 所對映的宿主機的埠號不能與master容器相同,因為其已經被master容器佔用;
  • 必須加上--link引數,其後指定了當前容器所要連線的容器,mysql-master表示所要連線的容器的名稱,master表示為該容器起的一個別名,通俗來講,就是slave容器通過這兩個名稱都可以訪問到master容器。這麼做的原因在於,如果master與slave不在同一個docker network中,那麼這兩個容器相互之間是沒法訪問的。注意這一點非常重要,之前本人按照網上的搭建方式搭建主從伺服器一直無法成功,主要就是因為他們一直沒有提到要設定這個引數。

        在啟動從容器之後,我們還是需要進入到從容器,並且連線上MySQL服務:

docker exec -it mysql-slave /bin/bash
mysql -uroot -proot

        連線上MySQL伺服器之後,我們就需要切換當前服務的狀態,使其能夠連線上master伺服器,並且複製其資料:

change master to master_host='master', master_user='test', master_password='123456', master_port=3306, master_log_file='mysql-bin.000014', master_log_pos=154, master_connect_retry=30;

        上述命令中,各個引數的含義其實比較好理解,主要就是指定master服務的域名(也就是我們前面link時使用的別名)、使用者名稱、密碼、埠,以及master節點的binlog檔案和log的position。這裡的binlog檔案和log的position就是前面我們show master status;命令的執行結果,讀者朋友需要與本機的實際結果一致。最後我們需要開啟主從複製:

start slave;

        開啟完成之後,我們可以通過如下命令檢視從伺服器的連線狀態:

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: master
                  Master_User: test
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000014
          Read_Master_Log_Pos: 154
               Relay_Log_File: 6774ae81bc25-relay-bin.000034
                Relay_Log_Pos: 367
        Relay_Master_Log_File: mysql-bin.000014
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
                         ....
             Master_Server_Id: 1
                  Master_UUID: 8976b929-bc8b-11e9-bab3-0242ac110005
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
                         ....
1 row in set (0.00 sec)

        這裡只要看到兩個引數Slave_IO_RunningSlave_SQL_Running都為true,則表示複製是正常進行的,到這裡我們的主從結構也就搭建完成了。

3. 測試主從服務

        測試主從服務比較簡單,只需要在master伺服器上執行相關的命令,然後檢查slave伺服器上是否存在相應的更新即可。我們可以在master節點上執行如下命令,建立一個數據庫和表,然後插入一條資料:

mysql> create database test;
Query OK, 1 row affected (0.01 sec)

mysql> use test;
Database changed

mysql> create table t_user(id bigint, name varchar(255));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t_user(id, name) value (1, 'Mary');
Query OK, 1 row affected (0.01 sec)

        然後我們連線上從資料庫,檢視其上是否有相關的更新:

mysql> select * from test.t_user;
+------+------+
| id   | name |
+------+------+
|    1 | Mary |
+------+------+
1 row in set (0.00 sec)

        可以看到,從伺服器上確實同步了相關的資料,這也進一步驗證了我們搭建的主從伺服器是OK的。

4. 小結

        本文主要講解了如何通過docker執行兩個MySQL容器,並且詳細介紹瞭如何將兩個容器連線起來,以及如何配置主從資