高可用叢集的基本特點
負載均衡 / 讀寫分離 / 故障轉移
本文以此為目標,利用 mysql-shell、mysql-router,基於 docker 的環境架構(篇幅太長,內容多了點兒)。
名詞 | 解釋 |
---|---|
GR | Group Replication;叢集間的主從節點資料複製,利用 gtid、binlog 等確保所有節點資料的一致。 |
DDL | Data Definition Language;操作庫本身的語句。如 CREATE/ALTER/DROP等語句;自動提交當前事務;不能回滾。 |
DML | Data Manipulation Language;針對資料的操作,如 CRUD,可回滾。 |
本文主要闡述內容:
名稱 | 標籤 | 角色 |
---|---|---|
Rockylinux | 9.1 | 本次整體測試虛擬機器器;可參考:https://rockylinux.org |
mysql-shell | 8.0.31 | 用來管理叢集 |
mysql-router | 8.0.31 | 叢集路由服務 |
docker | 20.10.22 | 叢集服務容器載體 |
docker image:oraclelinux | 9-slim | 用來部署 mysql-router 的映象 |
docker image:mysql | 8.0.31 | 叢集範例服務映象 |
mysql-cli | 8.0.31 | 用來測試驗證連線的使用者端 |
環境架構圖範例:
應用安裝層次圖:
- docker 的安裝在這裡省略。
- 網路地址全部使用 hostname 代替 IP 相互通訊。
- 所有 MySQL 系相關的應用版本計劃統一為 8.0.31。
- 所有 MySQL 涉及到的賬號,為了測試便捷,以下都用 root / 統一密碼操作。
mysql image:利用官方提供的映象,後續執行容器作為叢集的節點
oraclelinux image:官方提供的系統映象,後續為執行 mysql-router 的容器
# 拉取oraclelinux系統映象
docker pull oraclelinux:9-slim
# 拉取MySQL官網提供的映象
docker pull mysql:8.0.31
叢集,當然建議固定 ip,甚至設定叢集 hosts;這對於叢集內部網路高並行下是很有必要的網路優化。
為此,這裡單獨建立一個虛擬網路,後續應用到叢集中。(計劃本次測試不涉及跨主機的網路轉發)
# 這裡建立一個名稱為 br-mysql-clus 的自定義網路,計劃叢集所有節點處在同一網段下
docker network create --subnet=12.12.0.0/24 --gateway=12.12.0.254 br-mysql-clus
計劃叢集中的每個節點都用固定 IP,並指明 hostname,以 hostname 相互通訊(這在叢集中提升了通訊的效率)。
計劃所有的容器 hosts 檔案都繫結到 Linux VM 的/etc/hosts
;所以主機 hosts 設定所有節點的 IP > hostname:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# 追加叢集各節點的 IP > hostname
# 以下定義,為後續容器的執行做準備
12.12.0.1 mc1 # mysql cluster node 1
12.12.0.2 mc2 # mysql cluster node 2
12.12.0.3 mc3 # mysql cluster node 3
12.12.0.5 mr # mysql router
如果不設定以下各項,後續組建叢集的 shell 會逐一列出不符合叢集要求的項,並提醒完成必須的設定。
server_id
:叢集各節點唯一標識,必須為數位型;基於此設定會自動生成設定項 server_uuid 的值。
gtid_mode / dnforce_gtid_consistency
:開啟組複製 / 並保持事務的一致性,這個很重要。
group_replication_single_primary_mode
:本次計劃的 單主多從 叢集模式。
binlog_transaction_dependency_tracking
:叢集同步資料時更精確的事務處理方式。
group_replication_group_name
:統一的名稱才可識別為屬於同一個叢集。
[mysqld]
# 各節點的唯一識別,各節點cnf唯一不同之處,只能是數位
server_id = 1
# 開啟組複製的叢集資料同步功能
gtid_mode = ON
enforce_gtid_consistency = ON
# 指明單主多從模式
loose-group_replication_single_primary_mode = ON
loose-binlog_transaction_dependency_tracking = WRITESET
# 叢集名稱,必為有效的UUID
loose-group_replication_group_name = "a53e2dec-a5fe-11ed-99b8-080027c5c3a3"
什麼是 GTID
全域性事務識別符號;GTID 是建立的唯一識別符號,基於事務的資料複製,可以識別和跟蹤源伺服器上提交的每個事務,在源和拓撲伺服器上均唯一;它在源伺服器上提交併由任何副本應用,源和副本之間始終保留GTID,只要在源上提交的所有事務也在副本上提交,在源上提交的事務只能在副本上應用一次,就可以保證兩者之間的一致性。
設定項說明解釋:
group_replication_start_on_boot
:節點加入叢集時,自動開始複製 Master 資料功能,以保持節點間資料一致。
group_replication_bootstrap_group
:叢集啟動後是否作為 Master 節點,自動開始RG;建議都設為 OFF。
group_replication_local_address
:叢集內各節點之間,當前節點對外的通訊地址。
group_replication_group_seeds
:叢集啟動時,組建的基本節點。
[mysqld]
# 啟動後自動執行組複製,預設=ON
#loose-group_replication_start_on_boot = ON
# 重啟後的叢集以哪個範例的資料為準的複製同步過程
#loose-group_replication_bootstrap_group = OFF
# 明確本節點的對外通訊地址(不是必須,shell指令碼可覆蓋代替)
# 當 communication_stack = MYSQL 時,以下埠只能3306
# 當 communication_stack = XCOM 時,以下埠建議33061
#loose-group_replication_local_address="{host}:3306"
# 種子節點,由每個節點的通訊地址組成(不是必須,shell指令碼可覆蓋代替)
#loose-group_replication_group_seeds="{host}:3306,{host}:3306,{host}:3306"
需要注意的設定項 group_replication_bootstrap_group
假設1:所有節點都設為 OFF,重啟的叢集不會自動開始組複製(GR)功能
假設2:多節點設為 ON,系統分不清以哪個節點為基準的組複製(GR)功能(腦裂現象)
假設3:固定一個節點設為 ON,此節點的資料在叢集中不一定是最完整的
所以,重啟後的叢集,人為的選擇 Master,手動啟動組複製(GR)最為妥當
方案1:叢集啟動前,選好一臺 ON 作為 Master,叢集啟動後,需改為 OFF
方案2:在被人為認定的 Master 主機上,手動啟動GR,如下指令碼:
mysql> SET GLOBAL group_replication_bootstrap_group = ON;
mysql> START GROUP_REPLICATION USER='***', PASSWORD='***';
mysql> SET GLOBAL group_replication_bootstrap_group = OFF;
以下預設值都已符合叢集執行的基本要求,或者不同場景,您需要不同的設定。
log_bin
:二進位制紀錄檔,包括所有(DDL/DML)指令碼的執行記錄,用於實時主從資料同步/資料恢復。
log_replica_updates
:同步過來的二進位制更新紀錄檔,也需要記錄到自己的二進位制紀錄檔中;便於災難時的恢復。
binlog_format
:資料同步紀錄檔記錄的程度;一般的/更細的/混合的;當然ROW更細的紀錄檔會帶來更龐大的空間佔用。
[mysqld]
#log_bin = ON # default = ON
#log_replica_updates = ON # default = ON
#binlog_format = ROW # default = ROW
#master_info_repository = TABLE # default = TABLE
#relay_log_info_repository = TABLE # default = TABLE
什麼是 binlog
Binary Log;以二進位制的形式記錄了對於資料庫的變更過程。
binlog可設定單檔案大小,過期時間等;多用於:資料恢復、主從同步。binlog 的三種記錄方式:
STATEMENT:能夠記錄大多數的指令碼變更過程;
ROW:記錄所有的指令碼變更細節,空間佔用過大;
MIXED:不同方式壓縮記錄所有指令碼的變更,確保資料的一致性、準確性。
[mysqld]
# 持久化設定,預設=NO
# 引數或設定儲存起來,如:組建時產生的賬戶密碼,重啟後依然有效
#persisted_globals_load = ON
# 選舉權重百分比,預設=50,正序排列優先順序
#loose-group_replication_member_weight = 50
# 新版 預設=MYSQL,舊版預設=XCOM
# 各節點通訊埠不可隨意使用:MYSQL必須用3306,XCOM可以用33061
# group_replication_communication_stack = MYSQL
# 事務寫入演演算法方式(組複製預設的XXHASH64,<=8.0.1版本預設值為OFF)
#transaction_write_set_extraction = XXHASH64
# 設定群組白名單,包含在內的節點才能加入
#(舊版本CommunicationStack=XCOM時有效)
#loose-group_replication_ip_whitelist="192.168.1.0/24"
# 複製單位大小;預設 150000000 位元組,可適當加大以提升複製效率
#loose-group_replication_transaction_size_limit = 1500000000
# 資料複製時,外來鍵級聯檢測;本次測試不需要那麼嚴謹,預設=OFF
#loose-group_replication_enforce_update_everywhere_checks = OFF
# 為建立 InnoDB Cluster,所要遮蔽的庫表型別,預設值如下
#disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
以上 cnf 中絕大多數的設定項,在後續 shell 管理叢集時,都會有對應的引數設定,以覆蓋 cnf 原有設定
這裡以[4.1 必須設定項]為模板,分別建立三個 cnf 組態檔:mc1.cnf
、mc2.cnf
、mc3.cnf
。
後續容器啟動時,分別對應各自節點的 cnf 檔案。各 cnf 唯一不同的設定項是server_id
。
這裡假設三個SQL範例(叢集至少),用 docker container 啟動執行起來。
執行容器為叢集必要的繫結項:
以下唯一不同的是:hostname、ip、container-name、cnf 項。
# 第一個SQL容器的啟動
docker run -dit \
--restart unless-stopped \ # 非人為宕機後自動重啟
-e LANG=C.utf8 \ # 設定系統字元集
-e TZ=Asia/Shanghai \ # 設定系統時區
-e MYSQL_ROOT_PASSWORD=sa. \ # SQL範例 root 密碼
--network br.mysql.clus \ # 使用的網路名稱(自定義建立的網路)
--ip 12.12.0.1 \ # 指定 IP,叢集模式建議固定 IP
--name mysql.clus.n1 \ # 容器名稱
--hostname mc1 \ # 容器內計算機名稱(用以叢集內的節點通訊)
-v /etc/hosts:/etc/hosts \ # 統一 hosts 設定
-v /my/mc1.cnf:/etc/my.cnf \ # 各範例的組態檔
mysql:8.0.31
# 第二個SQL容器的啟動
docker run -dit \
--restart unless-stopped \
-e LANG=C.utf8 -e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=sa. \
--network br.mysql.clus --ip 12.12.0.2 \
--name mysql.clus.n2 --hostname mc2 \
-v /etc/hosts:/etc/hosts \
-v /my/mc2.cnf:/etc/my.cnf \
mysql:8.0.31
# 第三個SQL容器的啟動
docker run -dit \
--restart unless-stopped \
-e LANG=C.utf8 -e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=sa. \
--network br.mysql.clus --ip 12.12.0.3 \
--name mysql.clus.n3 --hostname mc3 \
-v /etc/hosts:/etc/hosts \
-v /my/mc3.cnf:/etc/my.cnf \
mysql:8.0.31
記住以上三個容器的SQL映象提供的環境變數 MYSQL_ROOT_PASSWORD,也就是給 SQL Instance 的 root 設定密碼為 sa.;在後續的過程當中,都以 root 及這樣的密碼作為憑證。
叢集三個節點容器執行效果,這裡把各自節點容器名稱分別為:
mysql.clus.n1
mysql.clus.n2
mysql.clus.n3
作為叢集節點的管理工具,安裝在任意(Win/Linux)網路互通的系統都可以,這裡用官網提供的 [MySQL Yum Repository] 的方式安裝到 Linux VM
可參考官網:https://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/
# MySQL Yum Repository 安裝到 Linux 系統中
dnf install https://repo.mysql.com/mysql80-community-release-el9-1.noarch.rpm -y
dnf clean all && dnf makecache
# 在 Repository 中搜尋以 mysql-shell 為字首的應用
dnf list mysql-shell*
# 安裝特定版本的 mysql-shell
dnf install -y mysql-shell-8.0.31
這裡已經安裝過,截圖僅是搜尋並安裝的範例:
安裝完成後,進入 mysql-shell 命令列請輸入:mysqlsh
mysql-shell 提供了三種命令模式:JavaScript / python / sql;預設為 js 模式。
這裡說明一下接下來常用到的 mysqlsh 命令:
全域性物件 | 說明 |
---|---|
dba | 用於叢集的管理 |
mysql | SQL服務連線物件 |
shell | 通用函數 |
os | 與系統有關的操作 |
util | 工具函數 |
shell 通用命令 | 說明 |
\? ; \help | 獲得幫助 |
\js ; \py ; \sql | 切換模式 |
\ | 多行命令 |
\c ; \connect {user}:{host}:{port} | 連線到目標範例 |
\disconnect | 斷開連線對談 |
\reconnect | 重新連線到對談 |
\! ; \system | 執行系統指令碼 |
\q ; \quit ; \exit | 退出當前對談(mysql-shell) |
在接下來的過程當中,經常會用:
\js 方式組建管理 MySQL 叢集
\sql 方式查詢目標範例的資料資訊
在 mysqlsh 中,使用 MySQL AdminAPI 提供的dba
物件及函數來 檢測節點/建立叢集/設定叢集/解散叢集/重啟叢集 等的叢集管理操作。
有關於 AdminAPI 的研究,可參考官方檔案:https://dev.mysql.com/doc/mysql-shell/8.0/en/admin-api-userguide.html
接下來以dba
物件為主的叢集管理操作。
前期,已經執行了三個MySQL容器,參考[5.2 docker 啟動多個SQL範例容器],並且設定了執行叢集的必要引數;但在建立叢集前,通常都會檢驗目標範例是否符合加入叢集的要求:
先連線任意一個 Instance,比如:\c root@mc1:3306
(還記得 root 密碼麼,也許會讓你輸入憑證)
然後檢測所有節點的設定,是否符合叢集的基本執行條件(各 cnf 的必須設定項,未配好的會提醒):
# 分別檢測各節點(還記得先前設定的 hosts 各名稱麼)
dba.checkInstanceConfiguration('root@mc1:3306');
dba.checkInstanceConfiguration('root@mc2:3306');
dba.checkInstanceConfiguration('root@mc3:3306');
過程如下截圖範例:
如果檢測失敗
1、可用 \c 方式連線到目標範例後
2、再用 dba.configureLocalInstance(); 方法引導完成必須的設定
# 在任意目標範例中,建立名為 clus-1 的叢集
# 那麼,當前範例會被作為 Master 角色存在
var clus = dba.createCluster('clus-1');
# 或者,也可以指定目標範例名稱,建立叢集
# 如:dba.createCluster('clus-1',{localAddress:'root@mc2:3306'});
# 還記得名為 group_replication_local_address 的設定引數麼,所以以上 localAddress 的值會覆蓋此引數值
#
# 叢集建立完成後,可用 status(); 函數檢視當前叢集狀態資訊
clus.status();
#
# 也可以獲取當前節點所處的叢集
var clus1 = dba.getCluster();
從上圖可以看出:此節點為叢集的主節點、可讀可寫、單主多從模式、叢集內部通訊地址為 mc1:3306。
加入節點,需要設定資料恢復(與主節點保持一致)的方式:克隆、增量、自動。
可以加引數指明方式;也可以在新增過程中按系統提示選擇。
# 加入新的叢集節點,過程中通常選擇 Clone 模式來複制主節點的資料
clus.addInstance('root@mc2:3306');
clus.addInstance('root@mc3:3306');
# 當然也有提醒資訊;
# 比如:clus.addInstance('root@mc2:3306',{localAddress:'root@mc2:3306'});
# 追加的 localAddress 引數,更明確的指出此節點對叢集的通訊地址
# 所以也可省略的引數,mysqlsh 也可自動取範例 Uri 作為 localAddress 引數值
#
# 此時再 .status() 檢視叢集狀態
clus.status();
叢集新增新節點圖例:
叢集 .status() 狀態資訊圖例:
... ... 加入更多的節點;單主多從的叢集建立完成。
節點自動連線到叢集
當因為連線超時或效能壓力等,被自動踢出叢集的節點,恢復後自動連線到叢集;
或人為修復故障後,可以手動通過 rejoinInstance() 函數再次連線到叢集中;
被 removeInstance() 的節點恢復正常後,通過 addInstance() 再次加入叢集。
全域性函數 | 說明 |
---|---|
dba.configureLocalInstance(); |
設定當前節點為符合叢集的要求,不符合的設定項會自動提示。 |
dba.checkInstanceState({Uri}); |
檢查節點設定,列出節點的當前具體情況(衝突/分歧/錯誤)。 |
dba.configureInstance({Uri}, { option:value }); |
設定遠端SQL範例節點引數。 |
dba.checkInstanceConfiguration({Uri}); |
檢查指定節點是否符合加入叢集的要求。 |
dba.createCluster({cluster-name}); |
以指定(預設:當前)節點上下文為基準,建立一個叢集。 |
dba.getCluster({cluster-name}); |
取得當前節點所處/引數指定的叢集物件。 |
dba.rebootClusterFromCompleteOutage({cluster-name}); |
重啟指定的叢集(建議先 check 各節點) |
dba.dropMetadataSchema(); |
刪除整個 Schema(無法恢復)。 |
當前叢集物件函數 | 說明 |
{cluster}.addInstance({Uri}); |
叢集加入新節點。 |
{cluster}.status(); |
叢集狀態資訊。 |
{cluster}.describe(); |
叢集結構資訊。 |
{cluster}.removeInstance({Uri}); |
叢集內移除指定的節點範例。 |
{cluster}.rescan(); |
(屬於叢集)列出未執行在叢集內的節點範例。 |
{cluster}.rejoinInstance({Uri}); |
(故障節點修復後)重新連線到叢集。 |
{cluster}.foreQuorumUsingPartitionOf({Uri}); |
恢復叢集(建議先 check 各節點) |
{cluster}.dissolve(); |
解散叢集(各節點資料保持現狀)。 |
{cluster}.help({fun-name}); |
幫助;所有函數 或 指定函數。 |
{cluster}.options(); |
列出此叢集可配引數。 |
{cluster}.setOption({option}, {value}); |
為此叢集設定設定項。 |
{cluster}.setInstanceOption({Uri}, { option:value }); |
為此叢集的指定節點範例,設定設定項。 |
{cluster}.listRouters(); |
檢視路由資訊 |
{cluster}.setupAdminAccount({account-name}); |
為叢集中的所有節點統一建立相同的賬戶高許可權及密碼(替代root)。 |
{cluster}.setupRouterAccount({account-name}); |
為叢集中的路由統一建立相同的賬戶高許可權及密碼(替代root)。 |
函數應用場景案例:重啟叢集
可能預先要做的準備工作:在叢集中尋找資料集更接近完善的節點,以作為 Master 節點。
dba.rebootClusterFromCompleteOutage({ dryRun : true });
show variables like '%gtid_executed%';
引數應用場景案例:節點異常時踢出叢集前的延遲時長
當某個節點異常時,系統會有5秒的檢測時長,之後還會有延遲時長,後踢出叢集;為了防止被誤踢,延遲時長可配。
{cluster}.addInstance({Uri},{ expelTimeout : 8 });
{cluster}.setInstanceOption({Uri},{expelTimeout:8});
那,,,mysql-shell 管理的叢集有哪些引數可以設定的呢?
{cluster}.options();
函數列出每個節點的所有可設定引數:(擷取部分)
有沒有熟悉的引數。。。
這裡 options 所有的引數都與 cnf 組態檔引數一一對應;
比如:可以用dba.createCluster('{Uri}',{ key:value, key:value ... });
這樣的方式附帶引數
比如:可以用.addInstance('{Uri}',{ key:value, key:value ... });
這樣的方式附帶引數
也可以用函數.setOption( option, value );
這樣的方式完成引數設定。
用 mysql-shell 管理叢集時,預設情況下,以上都可覆蓋原有(my.cnf)設定,並可持久化(my-auto.cnf)儲存。
測試場景:在 Master 節點建立庫/表/資料後;檢視 Slave 節點是否已同步資料。
# 在 Master 節點建立庫/表/資料
\c root@mc1:3306
create database clusterdb;
create table clusterdb.emp(id bigint not null AUTO_INCREMENT,usercode VARCHAR(32) DEFAULT NULL,createtime datetime default now(),PRIMARY KEY (id));
insert into clusterdb.emp(usercode) values ('Sol'),('wang');
# 檢視 Slave 節點是否已同步資料
\c root@mc2:3306
select * from clusterdb.emp;
測試結果圖:主從資料同步完成。
測試場景:Master 節點製造宕機(停機),叢集選舉出新的 Master 節點,是否完成故障轉移。
1、假設的 Master 宕機:docker stop mysql.clus.n1
2、再檢視叢集 Master 角色所處節點。
# 連線到叢集節點
mysqlsh --uri root@mc2:3306
# 檢視叢集節點狀況
dba.getCluster().status();
測試結果上圖:其中 mc2:3306 節點已接替 Master 角色,完成故障轉移。
docker mysql-router 映象,官網有測試版,參考:https://hub.docker.com/r/mysql/mysql-router
既然非生產環境的穩定版,這裡在容器中安裝 mysql-router。
執行已有的 oraclelinux 映象,並進入容器:
# oraclelinux 映象執行出新容器
docker run -dit --restart unless-stopped -e LANG=C.utf8 -e TZ=Asia/Shanghai \
--name mysql.clus.mr --hostname mr \
--network br.mysql.clus --ip 12.12.0.5 \
-p 6446:6446 -p 6447:6447 \
-v /etc/hosts:/etc/hosts \
oraclelinux:9-slim
# 進入容器
docker exec -it mysql.clus.mr bash
容器內安裝 mysql-router
通常:docker 映象的系統,只提供最基本的應用功能,最大程度的簡化,是 docker image 的特點之一。
所以:以下映象的容器內,yum/dnf 已被移除,rpm 也被簡化,但僅提供了最簡陋的應用安裝方式 microdnf。
當然:也可以通過 microdnf 來安裝上功能強大的 yum/dnf 等,以下繼續使用 microdnf 方式安裝應用。
# 這裡使用官方提供的 Yum Repository 方式安裝
curl -#O https://repo.mysql.com/mysql80-community-release-el9-1.noarch.rpm
rpm -ivh mysql80-community-release-el9-1.noarch.rpm
# 作為映象的微型系統,當然是僅提供基本功能
# yum/dnf 都沒了,當然也可以安裝上,這裡使用自帶的 microdnf 命令安裝
# 更新 Repos,為了後續更快的應用安裝(多等會)
microdnf clean all && microdnf makecache
# 模糊搜尋以 mysql-router 為字首的安裝包
microdnf repoquery mysql-router*
# 搜尋到的包,安裝指定版本;格式:{name}-{版本號}
microdnf install mysql-router-community-8.0.31 -y
# 檢視安裝效果
mysqlrouter -V
# 命令有多種可選引數,這裡用以下方式初始化 mysql-router 範例
# 叢集 Master主機的URI格式:{sql-user}:{pass}@{host}:{port}
mysqlrouter --bootstrap root:sa.@mc1:3306 --user=root --force
# 初始化後產生的組態檔可檢視,或修改設定項
cat /etc/mysqlrouter/mysqlrouter.conf
# 啟動後臺執行範例
mysqlrouter --user=root &
a、建立空資料夾,作為製作映象的根目錄;
b、資料夾中建立 Dockerfile 檔案:touch Dockerfile
;
Dockerfile 檔案內容如下:
# 基於 Oracle 9 Linux 系統的依賴
FROM oraclelinux:9-slim
# 系統預設字元集
ENV LANG C.utf8
# 系統預設時區
ENV TZ Asia/Shanghai
# mysql-router 用到的叢集 Master Uri 作為系統變數
# 叢集 Master Uri 格式為:{user}:{pass}@{host}:{port}
ENV MASTER_URI root:sa.@mc1:3306
# 以下執行在指定賬戶下
USER root
# 進入系統後的預設目錄
WORKDIR ~
# 製作系統所需的命令步驟
# - 網路安裝MySQL官網提供的 Yum Repository,編譯 mysql-router 在此 Repo 下安裝
RUN rpm -ivh https://repo.mysql.com/mysql80-community-release-el9-1.noarch.rpm
RUN microdnf clean all
RUN microdnf makecache
RUN microdnf install mysql-router-community-8.0.31 -y
RUN mysqlrouter --bootstrap $MASTER_URI -u=root --force
# 對外提供 mysql-router 的讀寫埠
EXPOSE 6446 6447
# mysql-router 初始化 並 啟動
ENTRYPOINT mysqlrouter -u=root
c、Dockerfile 檔案儲存退出後,在此目錄下執行 build 命令,生成 image 包。
# build 格式:docker build -t {image-name}:{tag} {根目錄}
docker build -t mysql/router8:1.0 .
# 檢視 image list
docker image ls
將製作的 mysql/router8 映象執行到容器
docker run -dit \
--restart unless-stopped \ # 非手動關機時自動重啟
--name mysql.clus.mr \ # 容器名稱
--hostname mr \ # 計算機名
--network br.mysql.clus \ # 指定網路
--ip 12.12.0.5 \ # 叢集時建議使用固定IP
-p 6446:6446 -p 6447:6447 \ # 對外開發的埠對映
-v /my/mr.hosts:/etc/hosts \ # 叢集時的 hosts 優化
-e MASTER_URI=root:sa.@mc2:3306 \ # 叢集 Master uri 地址
mysql/router8:1.0 # 使用製作的映象
範例節點 + 路由 的容器列表:
叢集檢視路由資訊:listRouters()
所以,,,使用者端在連線的時候,不同的動作連線對應的埠號。
首先,使用者端 mysql-cli 先連線到 mysql-router;
mysql-router 按叢集狀況,把讀寫動作連線到不同的叢集節點上。
測試辦法:使用者端 mysql-cli 連線 mysql-router 的寫入埠 6446,是否連線到 Master?
# mysql-cli 連線到 mysql-router
mysql -h mr -u root -P 6446 -p
# - 驗證連線的主機(是不是 mc1)
select @@hostname, @@port;
上圖測試結果顯示:路由的 6446 埠連線到 Master,並可寫入資料;測試通過。
測試辦法:使用者端 mysql-cli 連線 mysql-router 的唯讀埠 6447,是否連線到 Slave?
# mysql-cli 連線到 mysql-router
mysql -h mr -u router_newuser_1 -P 6447 -p
# - 驗證連線的主機(是不是 mc2,mc3)
select @@hostname, @@port;
# - 驗證資料是否已經同步到從機
select * from emp;
上圖測試結果顯示:路由的 6447 埠,連線到了 Slave 節點,並可查詢資料;測試通過。
測試場景:透過路由 6447 唯讀埠,多次連線查詢資料,是否輪詢連線到不同的唯讀節點?
上圖測試結果顯示:多次連線唯讀埠,連線到了不同的唯讀節點;測試通過。