最近因工作關係剛好研究到 MariaDB High Availability (HA) 機制,因此本篇整理一下 MariaDB Master-Slave Replication 的相關筆記。
在一個系統環境裡,資料庫通常扮演著很重要的角色,主要負責存放系統的一些紀錄或是使用者的資料,因此資料庫的備援/高可用性 (High Availability)以及負載平衡 (Load Balancing) 就變得相當重要。
目前 MariaDB 針對 High Availability 有以下常見的幾種方式:
- Master-Slave Replication (A-S Mode)
- Master-Master Replication (A-A Mode)
- Galera Cluster Master-Master (A-A Mode)
- Galera Cluster Master-Slave (A-S Mode)
本篇文章主要會探討的是最傳統的方式 Master-Slave Replication
。
Master-Slave Replication
Master-Slave Replication 主要是將多台 MariaDB 組成 Cluster,而這個 Cluster 裡,會有一台 MariaDB 扮演 Master
的角色,而其他 1~n 台會扮演著 Slave
的角色,Master 主要負責的動作為Read-Write;Slave 則負責 Read 以及同步 Master 的所有操作。
以下為最常見的架構,通常 Master 只會有一台,然後會有多台 Slave 不斷同步 Master 的工作,當 Master 掛掉時,管理者可以將 Slave 轉換成 Master 取代 Master 動作。
圖片來源: Replication Overview
因此在這種 Master-Slave Replication 架構下:
- 只能有一台 Master 存在,Master 可以處理 Read-Write 工作
- 可以有多台 Slave 存在,Slave 可以處理 Read 工作或是單純 Standby
- Slave 會不斷跟 Master 同步資料
- 支援 Read HA + LoadBalancing
- 支援 Write HA 但不支援 Load Balancing
💡 如果要考量 Write Load Balancing,就必須要有多台 Master 同時運作的情境,這種情境就要改使用 Master-Master Replication 或是 MariaDB Galera Cluster。
同步機制
圖片來源: HA for MySQL and MariaDB - Comparing Master-Master Replication to Galera Cluster
MariaDB Replication 主要透過 Binary Log 以及 Relay Log 的方式進行同步。
- Master 會將
CREATE
、ALTER
、INSERT
、UPDATE
還有DELETE
這些操作的步驟記錄在 BInary Log 裡面。 - Slave 會定期 Polling Master Binary Log (使用 MySQL API, 這間隔趨近 Real-Time),並將 Binary Log 資訊以及同步紀錄寫在自己的 Relay Log 裡面。
- Slave 最後根據 Relay Log 資訊來套用 SQL 到 Slave MariaDB 上。
- 完成同步。
設定步驟
此文章採用版本資訊如下:
- MariaDB 10.3.32
- Ubuntu 20.04 LTS
環境:
- Master MariaDB
192.168.89.131
- Slave MariaDB
192.168.89.132
以下步驟開始在 Master MariaDB 上操作
- 設定
my.cnf
檔,啟用 Binary Log1 2
mkdir /root/config touch /root/config/my.cnf
my.cnf
(在 Master-Slave Replication Cluster 裡,每台 MariaDBserver_id
需要不一樣)1 2 3 4 5
[mariadb] log-bin server_id=1 log-basename=master1 binlog-format=mixed
- 部署 Master MariaDB
1 2 3
export IP=192.168.89.131 docker run --name mariadb-master -p $IP:3306:3306 -v /root/config:/etc/mysql/conf.d -e MARIADB_ROOT_PASSWORD=123456 -d mariadb:10.3.32
此指令為測試用,若是在 Production,請記得設定加上 Persistent Data 存放目錄以及相關帳號設定,不要使用 Root。
- 建立 Replication 用的帳號
1 2 3
docker exec -it mariadb-master bash $ mysql -u root -p123456
1 2 3
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* to replicator@'%' IDENTIFIED BY 'secret'; MariaDB [(none)]> FLUSH PRIVILEGES; MariaDB [(none)]> FLUSH TABLES WITH READ LOCK;
- 查看 Master 資訊,需記下 Binary Log 名稱
1 2 3 4 5 6 7
MariaDB [(none)]> SHOW MASTER STATUS; + — — — — — — — — — + — — — — — + — — — — — — — + — — — — — — — — — + | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | + — — — — — — — — — + — — — — — + — — — — — — — + — — — — — — — — — + | master1-bin.000003 | 466 | | | + — — — — — — — — — + — — — — — + — — — — — — — + — — — — — — — — — + 1 row in set (0.00 sec)
以下步驟開始在 Slave MariaDB 上操作
- 設定
my.cnf
檔,啟用 Binary Log1 2
mkdir /root/config touch /root/config/my.cnf
my.cnf
(在 Master-Slave Replication Cluster 裡,每台 MariaDBserver_id
需要不一樣)1 2
[mariadb] server_id=2
- 部署 Slave MariaDB 。
1 2 3
export IP=<slave node IP> docker run --name mariadb-slave -p $IP:3306:3306 -v /root/config:/etc/mysql/conf.d -e MARIADB_ROOT_PASSWORD=123456 -d mariadb:10.3.32
此指令為測試用,若是在 Production,請記得設定加上 Persistent Data 存放目錄以及相關帳號設定,不要使用 Root。
- 設定連到 Master MariaDB,並啟用 Slave 服務,
CHANGE MASTER
根據 Master 資訊填寫。1 2 3
docker exec -it mariadb-slave bash $ mysql -u root -p123456
1 2 3
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.89.131', MASTER_USER='replicator', MASTER_PASSWORD='secret', MASTER_LOG_FILE='master1-bin.000003', MASTER_LOG_POS=466; MariaDB [(none)]> START SLAVE;
MASTER_LOG_FILE
代表要去讀 Master 的 Binary Log 名稱
MASTER_LOG_POS
代表要從 Binary Log 哪一個位置開始同步,需跟SHOW MASTER STATUS;
的Position
值一樣。 - 查看 Slave 資訊 (需確認
Slave_IO_Running
以及Slave_SQL_Running
是否為Yes
)1
MariaDB [(none)]> SHOW SLAVE STATUS;
以下步驟開始在 Master MariaDB 上操作
- UNLOCK Master MariaDB Table。
1
MariaDB [(none)]> UNLOCK TABLE ;
- 這樣就完成,可以嘗試看看透過 Master 進行寫入動作,Slave 那邊是否會同步。
1 2 3 4 5 6 7 8 9 10 11 12
MariaDB [(none)]> CREATE DATABASE hello; MariaDB [(none)]> USE hello; MariaDB [hello]> CREATE TABLE hellotable (`id` int, `name` varchar(10) ) ; MariaDB [hello]> INSERT INTO hellotable (`id`,`name`) VALUES ('1','pohsien') ; MariaDB [hello]> SELECT * FROM hellotable; +------+---------+ | id | name | +------+---------+ | 1 | pohsien | +------+---------+ 1 row in set (0.000 sec)
以下步驟開始在 Slave MariaDB 上操作
- 在 Slave 可以馬上看到剛剛在 Master 建立的 DB、Table 以及 Record。
1 2 3 4 5 6 7 8
MariaDB [(none)]> USE hello; MariaDB [hello]> SELECT * FROM hellotable; +------+---------+ | id | name | +------+---------+ | 1 | pohsien | +------+---------+ 1 row in set (0.000 sec)
- 後續可以搭配 HA Proxy 以及程式端設定讀寫分離,讓程式寫入資料時到 Master 上去寫,要讀的時候,就透過 HA Proxy Load Balancing 到任一台 Slave 去讀,可以提高效率以及增加高可用性。
💡 請注意,在 Master-Slave Replication 中同步是單向的,也就是只能 Master 同步給 Slave,並不能 Slave 同步給 Master,如果不小心在 Slave 寫入資料,會造成 split-brain 的嚴重情況,Cluster 同步會出問題。
Auto-Failover
MariaDB Master-Slave Replication 預設不支援動態 Failover,如果遇到 Master 故障,需要手動進行切換,將 Slave 啟用 binlog
,讓他變成 Master,然後剩下的 Slave 必須設定 CHANGE MASTER
來將他指到新的 Master,皆需要管理者手動設定。
另外在 Load Balancer 端,像 HA Proxy 這類型的 Load Balancer,也很難自動根據 MariaDB Master 或 Slave 角色變換調整 Server Pool,步驟相當繁瑣。
因此 MariaDB 官方釋出一個工具 MaxScale,他裡面包含了許多模組,例如 Monitor
模組,可以監看 MariaDB Cluster 狀態,並實現 auto-failover 以及 auto-rejoin (掛掉的 Node 恢復後主動加回 Cluster)。 Service
模組,可以實現路由,將流量導到正確身份的 MariaDB 身上,當有 Failover 發生後,也可以自動轉換流量導向,非常方便。
MaxScale 設定步驟
此文章採用版本資訊如下:
- MariaDB 10.3.32
- Ubuntu 20.04 LTS
- MaxScale 6.2.1
環境(總共有四台 VM):
- Master MariaDB
192.168.89.131
(server_id:1
) - Slave MariaDB-1
192.168.89.132
(server_id:2
) - Slave MariaDB-2
192.168.89.133
(server_id:3
) - MaxScale
192.168.89.134
- 參考 MariaDB MaxScale Installation Guide 安裝 MaxScale 以及設定完 MariaDB Master-Slave Cluster。
- 在 MaxScale VM 編輯 MaxScale 設定檔
1
$ vim /etc/maxscale.cnf
- 建立三台 MariaDB 資訊,
[]
名稱可以任意取名,這邊設定很像設定 Load Balancer 的 Server Pool (Backend) 一樣。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
... [server1] type=server address=192.168.89.131 port=3306 protocol=MariaDBBackend [server2] type=server address=192.168.89.132 port=3306 protocol=MariaDBBackend [server3] type=server address=192.168.89.133 port=3306 protocol=MariaDBBackend ...
- 設定 Monitor,監控 MariaDB 的狀態,其中這裡也可以設定
auto_failover
以及auto_rejoin
來實現 Master 身份自動轉移以及自動將排除異常的 Node 重新加回 Cluster。1 2 3 4 5 6 7 8 9 10 11 12 13
... [MariaDB-Monitor] type=monitor module=mariadbmon servers=server1,server2,server3 user=root password=123456 monitor_interval=2000 # 啟用自動 Failover auto_failover=true # 啟用自動 rejoin auto_rejoin=true ...
-
設定 Service (路由),預設是讀寫分開,這邊可以設定 Listener 以及 Backend,可以將讀寫切分成不同的 Listener,並對應到不同的 Backend。
在此我們將 Write 的動作都導向到 Master MariaDB 身上,Read 的動作則導向到 Slave MariaDB 身上,MaxScale 會自己判斷身份,所以只要將全部 MariaDB 都加進 Service 就好。
若要讀寫分開也必須看自己的 Application 是否有支援這樣設計
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
... #--------- Services (LoadBalancr 後端的 Server Pool) ---------- ## 給 Reqd-Only 使用 [Read-Only-Service] type=service router=readconnroute # 這邊設定要當作 Backend 的 Server servers=server1,server2,server3 user=maxscale password=123456 # 設定要作為 Backend 的種類,這裡表示會從 servers Group 裡面挑出 Slave 來做 LoadBalancing router_options=slave ## 給 Read-Write 使用 [Read-Write-Service] type=service router=readconnroute # 這邊設定要當作 Backend 的 Server servers=server1,server2,server3 user=maxscale password=123456 # 設定要作為 Backend 的種類,這裡表示會從 servers Group 裡面挑出 Master 來做 LoadBalancing router_options=master #----------- Listeners (LoadBalancr 前端的窗口) -------------- [Read-Only-Listener] type=listener service=Read-Only-Service protocol=MariaDBClient address=192.168.89.134 port=4008 [Read-Write-Listener] type=listener service=Read-Write-Service protocol=MariaDBClient port=4006 address=192.168.89.134 ...
💡 這邊的
user
password
是給 MaxScale 使用的,因為 MaxScale 主要接收 Client 連線的窗口,所以他會需要權限能夠讀 MariaDB 的 User 資訊以及連到 MariaDB 去做一些操作,例如修改 Master-Slave 設定,可查看 Creating a user account for MaxScale 。 - 完成後重啟 MaxScale,這樣設定完之後,連線資訊如下:
- Read 使用的連線資訊:
192.168.89.134:4008
- Write 使用的連線資訊:
192.168.89.134.4006
1
$ systemctl restart maxscale.service
- Read 使用的連線資訊:
- 在 MaxScale VM 查看 Monitor 資訊,如果把 Master 關機,可以看到 State 切換,也可以參考 Manual Failover 手動切換角色
maxctrl call command mariadbmon failover Monitor
。1 2 3 4 5 6 7 8 9 10
$ maxctrl list servers ┌─────────┬────────────────┬──────┬─────────────┬─────────────────┬──────────┐ │ Server │ Address │ Port │ Connections │ State │ GTID │ ├─────────┼────────────────┼──────┼─────────────┼─────────────────┼──────────┤ │ server1 │ 192.168.89.131 │ 3306 │ 0 │ Master, Running │ 0-3-7224 │ ├─────────┼────────────────┼──────┼─────────────┼─────────────────┼──────────┤ │ server2 │ 192.168.89.132 │ 3306 │ 0 │ Slave, Running │ 0-3-7224 │ ├─────────┼────────────────┼──────┼─────────────┼─────────────────┼──────────┤ │ server3 │ 192.168.89.133 │ 3306 │ 0 │ Slave, Running │ 0-3-7224 │ └─────────┴────────────────┴──────┴─────────────┴─────────────────┴──────────┘
- 透過 MaxScale 存取 MariaDB 測試 LoadBalancing 是否正確。
1 2
$ msql -h 192.168.89.134 -P 4006 -u myuser -p $ msql -h 192.168.89.134 -P 4008 -u myuser -p
💡 這邊的使用者是給 application 連線用的,這個需要注意,因為連線方式是:
client
→maxscale
→mariadb
,所以需要設定這個使用者能從client
端以及maxscale
連到 MariaDB,可參考 Creating client user accounts - 若透過
4006
port 成功連到 MariaDB,查看連到的 DB Server id,應該不管在哪裡連都會是 Master 那台 Node。1 2 3 4 5 6
MariaDB [(none)]> SELECT @@server_id ; +-------------+ | @@server_id | +-------------+ | 1 | +-------------+
- 若透過
4008
port 成功連到 MariaDB,查看連到的 DB Server id,應該會是任一台 Slave 。1 2 3 4 5 6
MariaDB [(none)]> SELECT @@server_id ; +-------------+ | @@server_id | +-------------+ | 3 | +-------------+
MaxScale with Keepalived
由於 MaxScale 會不斷偵測 MariaDB 異常以及提供 Load Balancing,如果 MaxScale 本身異常的話,會導致這些機制停掉,因此在 Production 環境 通常需要多台來達到 HA。
MariaDB 官方採用 Keepalived 來實現 MaxScale HA,可以參考 MaxScale HA setup using Keepalived and MaxCtrl 。
圖片來源: MaxScale HA setup using Keepalived and MaxCtrl
參考資料
Introduction
- HA for MySQL and MariaDB - Comparing Master-Master Replication to Galera Cluster
- Replication Overview
Setup Replication
- Setting Up Replication
- MariaDB Load Balancing with HAProxy on Centos 7
- MariaDB Replication: 2 Easy Methods
- How to Configure MariaDB Master-Master/Slave Replication?
MaxScale
- MariaDB MaxScale
- MariaDB MaxScale Installation Guide
- Automatic Failover With MariaDB Monitor
- Connection Routing with MariaDB MaxScale
- Setting up MariaDB MaxScale
- MariaDB MaxScale Configuration Guide
- MariaDB Load Balancing with HAProxy on Centos 7
- MaxScale HA setup using Keepalived and MaxCtrl
文章內容的轉載、重製、發佈,請註明出處: https://blog.phshih.com/