【MySQL】 在Docker中快速部署PXC
【MySQL】 在Docker中快速部署PXC
參考:
https://www.cnblogs.com/lonelyxmas/p/10584902.html
https://www.cnblogs.com/markLogZhu/p/11463125.html
一鍵部署PXC: https://github.com/luckman666/deploy_mysql_cluster
一、簡介
PXC屬於一套近乎完美的mysql高可用叢集解決方案,相比那些比較傳統的基於主從複製模式的叢集架構MHA和MM+keepalived,galera cluster最突出特點就是解決了詬病已久的資料複製延遲問題,基本上可以達到實時同步。而且節點與節點之間,他們相互的關係是對等的。本身galera cluster也是一種多主架構。galera cluster最關注的是資料的一致性,對待事物的行為時,要麼在所有節點上執行,要麼都不執行,它的實現機制決定了它對待一致性的行為非常嚴格,這也能非常完美的保證MySQL叢集的資料一致性;
對galera cluster的封裝有兩個,雖然名稱不同,但實質都是一樣的,使用的都是galera cluster。一個MySQL的創始人在自己全新的MariaDB上實現的MAriaDB cluster;一個是著名的MySQL服務和工具提供商percona實現的percona xtradb cluster,簡稱PXC
要搭建PXC架構至少需要3個mysql例項來組成一個叢集,三個例項之間不是主從模式,而是各自為主,所以三者是對等關係,不分從屬,這就叫multi-master架構。客戶端寫入和讀取資料時,連線哪個例項都是一樣的。讀取到的資料時相同的,寫入任意一個例項之後,叢集自己會將新寫入的資料同步到其他例項上,這種架構不共享任何資料,是一種高冗餘架構。
PXC的操作流程:
首先客戶端先發起一個事務,該事務先在本地執行,執行完成之後就要發起對事務的提交操作了。在提交之前需要將產生的複製寫集廣播出去,然後獲取到一個全域性的事務ID號,一併傳送到另一個節點上面。通過合併資料之後,發現沒有衝突資料,執行apply_cd和commit_cb動作,否則就需要取消此次事務的操作。而當前server節點通過驗證之後,執行提交操作,並返回OK,如果驗證沒通過,則執行回滾。當然在生產中至少要有3個節點的叢集環境,如果其中一個節點沒有驗證通過,出現了資料衝突,那麼此時採取的方式就是講出現不一致的節點踢出叢集環境,而且它自己會執行shutdown命令,自動關機。
PXC的優點:
①實現mysql資料庫叢集架構的高可用性和資料的 強一致性。
②完成了真正的多節點讀寫的叢集方案。
③改善了傳統意義上的主從複製延遲問題,基本上達到了實時同步。
④新加入的節點可以自動部署,無須提供手動備份,維護起來很方便。
⑤由於是多節點寫入,所以資料庫故障切換很容易。
PXC的缺點:
①新加入的節點開銷大,需要複製完整的資料。採用SST傳輸開銷太大。
②任何更新事務都需要全域性驗證通過,才會在每個節點庫上執行。叢集效能受限於效能最差的節點,也就是經常說的短板效應。
③因為需要保證資料的一致性,所以在多節點併發寫時,鎖衝突問題比較嚴重。
④存在寫擴大問題,所有的節點上都會發生些操作。
⑤只支援innodb儲存引擎的表。
⑥沒有表級別的鎖定,執行DDL語句操作會把整個叢集鎖住,而且也 kill 不了(建議使用Osc操作,即線上DDL)
⑦所有的表必須含有主鍵,不然運算元據時會報錯。
二、環境配置
1、系統:centos7.3
2、docker版本:Docker version 1.13.1, build 07f3374/1.13.1
3、PXC映象:percona/percona-xtradb-cluster
三、安裝部署
1、拉取映象
docker pull percona/percona-xtradb-cluster
成功拉取後的效果如圖所示:
2、建立docker內部網路
docker network create --subnet=172.18.0.0/24 net1
成功建立的效果如圖所示,使用docker network inspect net1命令檢視:
建立網路時出現以下錯誤資訊,莫慌,重啟docker再次建立即可
3、建立docker卷
docker volume create --name v1 docker volume create --name v2 docker volume create --name v3 docker volume create --name v4 docker volume create --name v5
4、檢視docker卷資訊
docker inspect v1 docker inspect v2 docker inspect v3 docker inspect v4 docker inspect v5
效果如圖所示
PS:切記一定要先建立docker卷再建立容器,不能一起來或者會報許可權異常,不能建立容器
5、建立容器,這裡以建立5個容器為例
docker run -di -p 3306:3306 \ -v v1:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -e CLUSTER_NAME=PXC \ -e XTRABACKUP_PASSWORD=123456 \ --privileged=true --name=node1 --net=net1 --ip 172.18.0.2 \ docker.io/percona/percona-xtradb-cluster docker run -di -p 3307:3306 \ -v v2:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -e CLUSTER_NAME=PXC \ -e XTRABACKUP_PASSWORD=123456 \ -e CLUSTER_JOIN=node1 \ --privileged=true --name=node2 --net=net1 --ip 172.18.0.3 \ docker.io/percona/percona-xtradb-cluster docker run -di -p 3308:3306 \ -v v3:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -e CLUSTER_NAME=PXC \ -e XTRABACKUP_PASSWORD=123456 \ -e CLUSTER_JOIN=node1 \ --privileged=true --name=node3 --net=net1 --ip 172.18.0.4 \ docker.io/percona/percona-xtradb-cluster docker run -di -p 3309:3306 \ -v v4:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -e CLUSTER_NAME=PXC \ -e XTRABACKUP_PASSWORD=123456 \ -e CLUSTER_JOIN=node1 \ --privileged=true --name=node4 --net=net1 --ip 172.18.0.5 \ docker.io/percona/percona-xtradb-cluster docker run -di -p 3310:3306 \ -v v5:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ -e CLUSTER_NAME=PXC \ -e XTRABACKUP_PASSWORD=123456 \ -e CLUSTER_JOIN=node1 \ --privileged=true --name=node5 --net=net1 --ip 172.18.0.6 \ docker.io/percona/percona-xtradb-cluster
PS:切記因第一個節點初始化比較耗時一定要等第一個容器建立成功可以使用MySQL客戶端連線了才能建立第二個,或者會報錯建立不了下面的容器!!!
效果如圖:
6、測試叢集
1)在node1對應的資料庫(pxc-mysql-1)建立資料庫mytest
2) 在node5對應的資料庫(pxc-mysql-5)檢視有沒有剛剛在node1所建立的資料庫mytest
3) 在node5對應的資料庫(pxc-mysql-5)建立一個表mytb,並插入一條資料
4) 在node1對應的資料庫(pxc-mysql-1)、node2對應的資料庫(pxc-mysql-2)檢視是否有剛剛新建的表和資料
MySQL之PXC叢集搭建
一、PXC 介紹
1.1 PXC 簡介
PXC 是一套 MySQL 高可用叢集解決方案,與傳統的基於主從複製模式的叢集架構相比 PXC 最突出特點就是解決了詬病已久的資料複製延遲問題,基本上可以達到實時同步。而且節點與節點之間,他們相互的關係是對等的。PXC 最關注的是資料的一致性,對待事物的行為時,要麼在所有節點上執行,要麼都不執行,它的實現機制決定了它對待一致性的行為非常嚴格,這也能非常完美的保證 MySQL 叢集的資料一致性;
1.2 PXC特性和優點
-
完全相容 MySQL。
-
同步複製,事務要麼在所有節點提交或不提交。
-
多主複製,可以在任意節點進行寫操作。
-
在從伺服器上並行應用事件,真正意義上的並行複製。
-
節點自動配置,資料一致性,不再是非同步複製。
-
故障切換:因為支援多點寫入,所以在出現資料庫故障時可以很容易的進行故障切換。
-
自動節點克隆:在新增節點或停機維護時,增量資料或基礎資料不需要人工手動備份提供,galera cluster會自動拉取線上節點資料,叢集最終會變為一致;
PXC最大的優勢:強一致性、無同步延遲
1.3 PXC的侷限和劣勢
-
複製只支援
InnoDB
引擎,其他儲存引擎的更改不復制 -
寫入效率取決於節點中最慢的一臺
1.4 PXC與Replication的區別
Replication | PXC |
---|---|
資料同步是單向的,master負責寫,然後非同步複製給slave;如果slave寫入資料,不會複製給master。 | 資料同步時雙向的,任何一個mysql節點寫入資料,都會同步到叢集中其它的節點。 |
非同步複製,從和主無法保證資料的一致性 | 同步複製,事務在所有叢集節點要麼同時提交,要麼同時不提交 |
1.5 PXC 常用埠
-
3306:資料庫對外服務的埠號。
-
4444:請求SST的埠。
-
4567:組成員之間進行溝通的一個埠號
-
4568:用於傳輸IST。
名詞解釋:
-
SST(State Snapshot Transfer): 全量傳輸
-
IST(Incremental state Transfer):增量傳輸
二、實踐
2.1 搭建 PXC 叢集
與
MySQL
不同的是 PXC 官方提供了
Docker
映象,所以我們可以很方便的搭建 PXC 叢集。
1)下載
Docker
映象
docker pull percona/percona-xtradb-cluster:5.7
- 重新命名映象名稱
docker tag percona/percona-xtradb-cluster:5.7 pxc:5.7
3)刪除原始映象
docker rmi percona/percona-xtradb-cluster:5.7
- 建立
Docker
網路,用於PXC
叢集獨立使用
docker network create pxc-network
- 建立資料卷用於之後掛載
docker volume create --name v1 docker volume create --name v2 docker volume create --name v3
注:
PXC
容器只支援資料卷掛載方式,不支援目錄掛載
- 建立第一個節點
docker run -di --name=pn1 --net=pxc-network -p 9000:3306 -v v1:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=cluster1 -e XTRABACKUP_PASSWORD=123456 pxc:5.7
因為後續節點的新增需要關聯到第一個節點,所以需要等待資料庫啟動完成。通過
docker logs pn1
檢視日誌,如果出現下面的輸出,證明啟動成功:
2019-09-04T06:27:30.085880Z 0 [Note] InnoDB: Buffer pool(s) load completed at 190904 6:27:30
注:CLUSTER_NAME 名稱不要用關鍵字
PXC
,否則無法啟動。
- 加入第二個節點
docker run -di --name=pn2 --net=pxc-network -p 9001:3306 -v v2:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=cluster1 -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pn1 pxc:5.7
需要注意是第二個節點開始需要增加
e CLUSTER_JOIN=pn1
引數,表示與
pn1
節點同步,否則
pn1
容器會自動關閉。
當
PXC
叢集中存在兩個節點以上之後就沒有主節點的概念了。叢集中最後一個退出的節點就會變為主節點,在
/var/lib/mysql/grastate.dat
檔案中屬性
safe_to_bootstrap
的值 會從
0
被設定為
1
表示該節點是主節點。
8)加入第三個節點
docker run -di --name=pn3 --net=pxc-network -p 9002:3306 -v v3:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=cluster1 -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pn2 pxc:5.7
可以看到我們這次我們
CLUSTER_JOIN
的是
pn2
容器,可以證明我們剛剛說的
當 PXC 叢集存在兩個節點以上之後就沒有主節點的概念了 這個說法是正確的。
9)進入
pn1
節點
docker exec -it pn1 /usr/bin/mysql -uroot -p123456
- 檢視狀態
mysql> show status like 'wsrep%'; +----------------------------------+-------------------------------------------------+ | Variable_name | Value | +----------------------------------+-------------------------------------------------+ | wsrep_local_state_uuid | 068dd5e8-cedd-11e9-904d-466e75bd8fe1 | | wsrep_protocol_version | 9 | | wsrep_last_applied | 16 | | wsrep_last_committed | 16 | | wsrep_replicated | 0 | | wsrep_replicated_bytes | 0 | | wsrep_repl_keys | 0 | | wsrep_repl_keys_bytes | 0 | | wsrep_repl_data_bytes | 0 | | wsrep_repl_other_bytes | 0 | | wsrep_received | 10 | | wsrep_received_bytes | 800 | | wsrep_local_commits | 0 | | wsrep_local_cert_failures | 0 | | wsrep_local_replays | 0 | | wsrep_local_send_queue | 0 | | wsrep_local_send_queue_max | 1 | | wsrep_local_send_queue_min | 0 | | wsrep_local_send_queue_avg | 0.000000 | | wsrep_local_recv_queue | 0 | | wsrep_local_recv_queue_max | 2 | | wsrep_local_recv_queue_min | 0 | | wsrep_local_recv_queue_avg | 0.100000 | | wsrep_local_cached_downto | 0 | | wsrep_flow_control_paused_ns | 0 | | wsrep_flow_control_paused | 0.000000 | | wsrep_flow_control_sent | 0 | | wsrep_flow_control_recv | 0 | | wsrep_flow_control_interval | [ 173, 173 ] | | wsrep_flow_control_interval_low | 173 | | wsrep_flow_control_interval_high | 173 | | wsrep_flow_control_status | OFF | | wsrep_cert_deps_distance | 0.000000 | | wsrep_apply_oooe | 0.000000 | | wsrep_apply_oool | 0.000000 | | wsrep_apply_window | 0.000000 | | wsrep_commit_oooe | 0.000000 | | wsrep_commit_oool | 0.000000 | | wsrep_commit_window | 0.000000 | | wsrep_local_state | 4 | | wsrep_local_state_comment | Synced | | wsrep_cert_index_size | 0 | | wsrep_cert_bucket_count | 22 | | wsrep_gcache_pool_size | 1592 | | wsrep_causal_reads | 0 | | wsrep_cert_interval | 0.000000 | | wsrep_open_transactions | 0 | | wsrep_open_connections | 0 | | wsrep_ist_receive_status | | | wsrep_ist_receive_seqno_start | 0 | | wsrep_ist_receive_seqno_current | 0 | | wsrep_ist_receive_seqno_end | 0 | | wsrep_incoming_addresses | 172.19.0.2:3306,172.19.0.3:3306,172.19.0.4:3306| | wsrep_cluster_weight | 3 | | wsrep_desync_count | 0 | | wsrep_evs_delayed | | | wsrep_evs_evict_list | | | wsrep_evs_repl_latency | 0/0/0/0/0 | | wsrep_evs_state | OPERATIONAL | | wsrep_gcomm_uuid | 11ed51e2-cedd-11e9-b362-af453a7ac074 | | wsrep_cluster_conf_id | 3 | | wsrep_cluster_size | 3 | | wsrep_cluster_state_uuid | 068dd5e8-cedd-11e9-904d-466e75bd8fe1 | | wsrep_cluster_status | Primary | | wsrep_connected | ON | | wsrep_local_bf_aborts | 0 | | wsrep_local_index | 0 | | wsrep_provider_name | Galera | | wsrep_provider_vendor | Codership Oy <info@codership.com> | | wsrep_provider_version | 3.37(rff05089) | | wsrep_ready | ON | +----------------------------------+-------------------------------------------------+ 71 rows in set (0.06 sec)
可以看到
wsrep_incoming_addresses
的值就是我們三個容器的IP地址
| wsrep_incoming_addresses | 172.19.0.2:3306,172.19.0.3:3306,172.19.0.4:3306 |
叢集完整性檢查:
屬性 | 含義 |
---|---|
wsrep_cluster_state_uuid | 在叢集所有節點的值應該是相同的,有不同值的節點,說明其沒有連線入叢集. |
wsrep_cluster_conf_id | 正常情況下所有節點上該值是一樣的.如果值不同,說明該節點被臨時”分割槽”了.當節點之間網路連線恢復 的時候應該會恢復一樣的值. |
wsrep_cluster_size | 如果這個值跟預期的節點數一致,則所有的叢集節點已經連線. |
wsrep_cluster_status | 叢集組成的狀態.如果不為”Primary”,說明出現”分割槽”或是”split-brain”腦裂狀況. |
節點狀態檢查:
屬性 | 含義 |
---|---|
wsrep_ready | 該值為 ON,則說明可以接受 SQL 負載.如果為 Off,則需要檢查 wsrep_connected |
wsrep_connected | 如果該值為 Off,且 wsrep_ready 的值也為 Off,則說明該節點沒有連線到叢集.(可能是 wsrep_cluster_address 或 wsrep_cluster_name 等配置錯造成的.具體錯誤需要檢視錯誤日誌) |
wsrep_local_state_comment | 如果 wsrep_connected 為 On,但 wsrep_ready 為 OFF,則可以從該項檢視原因 |
複製健康檢查:
屬性 | 含義 |
---|---|
wsrep_flow_control_paused | 表示複製停止了多長時間.即表明叢集因為 Slave 延遲而慢的程度.值為 0~1,越靠近 0 越好,值為 1 表示 複製完全停止.可優化 wsrep_slave_threads 的值來改善 |
wsrep_cert_deps_distance | 有多少事務可以並行應用處理.wsrep_slave_threads 設定的值不應該高出該值太多 |
wsrep_flow_control_sent | 表示該節點已經停止複製了多少次 |
*wsrep_local_recv_queue_avg | 表示 slave 事務佇列的平均長度.slave 瓶頸的預兆. 最慢的節點的 wsrep_flow_control_sent 和 wsrep_local_recv_queue_avg 這兩個值最高.這兩個值較低的話,相對更好 |
檢測慢網路問題:
屬性 | 含義 |
---|---|
wsrep_local_send_queue_avg | 網路瓶頸的預兆.如果這個值比較高的話,可能存在網路瓶頸 |
衝突或死鎖的數目:
屬性 | 含義 |
---|---|
wsrep_last_committed | 最後提交的事務數目 |
wsrep_local_cert_failures 和 wsrep_local_bf_aborts | 回滾,檢測到的衝突數目 |
2.2 叢集同步驗證
- 在節點一上建立資料庫
test
mysql> create database test; Query OK, 1 row affected (0.02 sec)
- 節點二上檢視:
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | +--------------------+ 5 rows in set (0.00 sec)
- 在節點二上建立表
mysql> use test; Database changed mysql> create table sys_user(id int ,name varchar(30)); Query OK, 0 rows affected (0.11 sec)
4)在節點三上檢視錶結構
mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | sys_user | +----------------+1 row in set (0.00 sec)
- 在節點三上插入資料
mysql> insert into sys_user values(1,'a'); ERROR 1105 (HY000): Percona-XtraDB-Cluster prohibits use of DML command on a table (test.sys_user) without an explicit primary key with pxc_strict_mode = ENFORCING or MASTER
看到沒有顯示的主鍵就無法插入資料,我們修改下表結構:
alter table sys_user add primary key (id);
插入資料:
mysql> insert into sys_user values(1,'a'); Query OK, 1 row affected (0.05 sec)
6)在節點一檢視錶資料
mysql> select * from sys_user; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set (0.00 sec)
可以看到三個節點資料正常同步,並且都可讀可寫。
2.3 新增資料庫節點操作
當資料庫不夠用時,我們通常需要增加資料庫節點來分擔壓力,我們來演示一下新增節點的操作。
- 建立資料卷
docker volume create --name v4
2)新增容器
docker run -di --name=pn4 --net=pxc-network -p 9003:3306 -v v4:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=cluster1 -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pn3 pxc:5.7
要注意的是,這次
CLUSTER_JOIN
連的是
pn3
。
- 進入節點4檢視資料
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | +--------------------+5 rows in set (0.00 sec)
mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | sys_user | +----------------+ 1 row in set (0.00 sec)
mysql> select * from sys_user; +----+------+ | id | name | +----+------+ | 1 | a | +----+------+ 1 row in set (0.00 sec)
可以看到之前的資料也自動同步過來了。
2.4 當機操作
- 將節點
pn4
容器關閉,造成當機現象
docker stop pn4
- 在節點
pn2
上做檢視叢集狀態
mysql> show status like 'wsrep%';
...... | wsrep_local_state | 4 | | wsrep_local_state_comment | Synced | | wsrep_cert_index_size | 3 | ...... | wsrep_incoming_addresses | 172.19.0.4:3306,172.19.0.3:3306,172.19.0.2:3306 |
可以看到叢集應該有4個節點,但是現在只有3個正常連線。
3)在節點
pn2
上做修改操作
mysql> update sys_user set name='b' where id=1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0
- 將節點
pn4
容器啟動
[root@VM_0_15_centos ~]# docker start pn4
- 進入容器
pn4
檢視修改操作是否同步
docker exec -it pn4 /usr/bin/mysql -uroot -p123456
mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from sys_user; +----+------+ | id | name | +----+------+ | 1 | b | +----+------+ 1 row in set (0.00 sec)
可以看到節點正常加入叢集,並且資料也同步了。
pn4
是以指定主節點形式進入
PXC
叢集建立的容器,那麼
pn1
直接以自身為主節點啟動的容器會怎麼樣呢?我們來演示一下:
- 關閉
pn1
節點
docker stop pn1
- 在
pn2
節點上插入一條資料
mysql> insert into sys_user values('2','c'); Query OK, 1 row affected (0.01 sec)
- 啟動
pn1
節點
docker start pn1
等待一分鐘,檢視容器啟動列表
docker ps -a
發現
pn1
節點並沒有啟動
CONTAINER ID IMAGE ...... STATUS NAMES fa123563e787 pxc:5.7 ...... Exited (1) About a minute ago pn1
檢視下錯誤日誌:
docker logs pn1
異常資訊如下:
2019-09-04T07:21:56.412918Z 0 [ERROR] WSREP: It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1 .2019-09-04T07:21:56.412922Z 0 [ERROR] WSREP: Provider/Node (gcomm://) failed to establish connection with cluster (reason: 7)2019-09-04T07:21:56.412929Z 0 [ERROR] Aborting
翻譯成中文:
2019-09-04T07:21:56.412918Z 0 [錯誤] WSREP:從此節點引導群集可能不安全。 它不是離開群集的最後一個,可能不包含所有更新。 要使用此節點強制群集引導,請手動編輯grastate.dat檔案並將safe_to_bootstrap設定為1。2019-09-04T07:21:56.412922Z 0 [錯誤] WSREP:提供者/節點(gcomm://)無法與群集建立連線(原因:7)2019-09-04T07:21:56.412929Z 0 [錯誤]中止
錯誤提示很明顯了,因為
pn1
節點不是最後一個離開叢集的不能再以主節點的形式啟動了,如果要以主節點的形式啟動必須調整
grastate.dat
檔案中的
safe_to_bootstrap
引數為
1
。
但是要注意的是因為叢集中其他節點並沒有關閉,這樣啟動的容器跟之前的叢集就沒有關係了資料也不會同步,我們來驗證下看看:
- 檢視資料卷存放的路徑
docker volume inspect v1
[ { "CreatedAt": "2019-09-05T09:22:22+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/v1/_data", "Name": "v1", "Options": {}, "Scope": "local" } ]
- 進入資料卷目錄,檢視是否存在
grastate.dat
檔案
[root@VM_0_15_centos ~]# cd /var/lib/docker/volumes/v1/_data [root@VM_0_15_centos _data]# ll total 323444-rw-r----- 1 1001 1001 56 Sep 5 08:34 auto.cnf -rw------- 1 1001 1001 1680 Sep 5 08:34 ca-key.pem -rw-r--r-- 1 1001 1001 1120 Sep 5 08:34 ca.pem -rw-r--r-- 1 1001 1001 1120 Sep 5 08:34 client-cert.pem -rw------- 1 1001 1001 1676 Sep 5 08:34 client-key.pem -rw-r----- 1 1001 1001 2 Sep 5 08:34 fa123563e787.pid -rw-r----- 1 1001 1001 134219048 Sep 5 09:22 galera.cache -rw-r----- 1 1001 1001 113 Sep 5 09:21 grastate.dat -rw-r----- 1 1001 1001 1300 Sep 5 08:34 ib_buffer_pool -rw-r----- 1 1001 1001 79691776 Sep 5 09:15 ibdata1 -rw-r----- 1 1001 1001 50331648 Sep 5 09:15 ib_logfile0 -rw-r----- 1 1001 1001 50331648 Sep 5 08:34 ib_logfile1 -rw-r----- 1 1001 1001 12582912 Sep 5 08:38 ibtmp1 -rw-r----- 1 1001 1001 34751 Sep 5 08:38 innobackup.backup.log drwxr-x--- 2 1001 1001 4096 Sep 5 08:34 mysql drwxr-x--- 2 1001 1001 4096 Sep 5 08:34 performance_schema -rw------- 1 1001 1001 1676 Sep 5 08:34 private_key.pem -rw-r--r-- 1 1001 1001 452 Sep 5 08:34 public_key.pem -rw-r--r-- 1 1001 1001 1120 Sep 5 08:34 server-cert.pem -rw------- 1 1001 1001 1676 Sep 5 08:34 server-key.pem drwxr-x--- 2 1001 1001 12288 Sep 5 08:34 sys drwxr-x--- 2 1001 1001 4096 Sep 5 09:07 test -rw-r--r-- 1 1001 1001 143 Sep 5 09:22 version_info -rw-r----- 1 1001 1001 3932160 Sep 5 09:15 xb_doublewrite
- 編輯檔案
vim grastate.dat
將
safe_to_bootstrap
引數值修改為1,儲存退出
# GALERA saved state version: 2.1uuid: 068dd5e8-cedd-11e9-904d-466e75bd8fe1 seqno: 20safe_to_bootstrap: 1
- 重啟
pn1
容器
docker start pn1
- 進入容器,檢視資料
docker exec -it pn1 /usr/bin/mysql -uroot -p123456
mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from sys_user; +----+------+ | id | name | +----+------+ | 1 | b | +----+------+1 row in set (0.01 sec)
發現資料並沒有同步,那麼要怎麼將
pn1
節點加入到叢集中呢?
我們可以直接將
pn1
容器刪除,以加入節點的形式重新建立容器,並且因為我們之前已經將容器的資料掛載到資料捲了,所以資料也不會存在丟失的風險,我們來操作下:
- 刪除
pn1
容器
docker stop pn1 docker rm pn1
- 以從節點方式加入叢集
docker run -di --name=pn1 --net=pxc-network -p 9000:3306 -v v1:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=cluster1 -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pn2 pxc:5.7
等待容器初始化完畢
3)進入容器,檢視資料是否同步
docker exec -it pn1 /usr/bin/mysql -uroot -p123456
mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from sys_user; +----+------+ | id | name | +----+------+ | 1 | b | | 2 | c | +----+------+2 rows in set (0.00 sec)
發現資料已經同步了。
一鍵部署PXC: https://github.com/luckman666/deploy_mysql_cluster
git clone https://github.com/luckman666/deploy_mysql_cluster.git
cd deploy_mysql_cluster && chmod -R 755 .
# 編輯 bash.config 引數
./deploy_mysql_master.sh
以上幾步就完成了一套多節點多主多從故障自動切換的mysql 資料庫叢集。
使用及注意事項:
如果叢集出現某一節點出現故障:
1 、叢集會立刻將其剔除叢集,停止同步。
2 、(主節點故障) keepalived 兩秒內會感知 mysql 故障,從叢集中踢除本節點 mysql ,本節點降權並將 VIP 漂移至完好節點,整個叢集繼續提供服務。
3 、(從節點故障) keepalived 直接關閉該節點服務,將該節點剔除叢集。
故障修復後加入叢集方式:
恢復節點上執行此命令(注意修改引數):
docker run -d -p 3306:3306 -p 4444:4444 -p 4567:4567 -p 4568:4568 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e CLUSTER_JOIN= 主節點主機名( mysql1 ) -e XTRABACKUP_PASSWORD=root -v /opt/mysql/data:/var/lib/mysql -v /opt/mysql/backup:/data -v /etc/localtime:/etc/localtime:ro -v /var/run/docker.sock:/var/run/docker.sock --privileged --name= 本節點主機名(如: mysql2 ) --net=swarm_mysql docker.io/percona/percona-xtradb-cluster
同步完成後啟動再keepalived
systemctl restart keepalived
檢查keepalived 啟動狀態
systemctl status keepalived
通過工具或者檢視容器日誌檢視mysql 執行是否良好!
設計這套mysql 的叢集方案主要是面向我司的賬單系統。因為都是賬單資料,對於資料的丟失的容忍度為 0 。所以採用多節點強制同步的 PXC 叢集方式。部署採用 docker 方式,網路方案採用 swarm 的 overlay 網路,冗餘策略是 keepalived
「實戰篇」開源專案docker化運維部署-搭建mysql叢集(四)
有了docker虛擬機器,就需要利用平臺部署資料庫的叢集,在實際操作之前介紹下資料庫叢集的方案和各自的特點。原始碼: https://github.com/limingios/netFuture/tree/master/mysql-pxc/
叢集的方案
單節點的弊病
- 大型網際網路程式使用者群體龐大,所以架構必須要特殊設計
- 單節點的資料庫無法滿足效能的要求
案例15年前,高考成績可以在網上查(河南幾十萬考生),那時候基本家裡都沒電腦,都是去網咖白天去網咖也查不了,太慢了,後來半夜通宵有時候可以查到,也就是說白天基本查不了人太多了。晚上看運氣。一個資料庫的例項1萬多人就無法反應了。
- 單節點的資料庫沒有冗餘設計,無法滿足高可用
常用的mysql叢集設計方案
- Replication
- 速度快
- 弱一致性
- 低價值
- 場景:日誌,新聞,帖子
- PXC
- 速度慢
- 強一致性
- 高價值
- 場景:訂單,賬戶,財務
Percona Xtradb Cluster,簡稱PXC。是基於Galera外掛的MySQL叢集。相比那些比較傳統的基於主從複製模式的叢集架構MHA和MM+keepalived,galera cluster最突出特點就是解決了詬病已久的資料複製延遲問題,基本上可以達到實時同步。而且節點與節點之間,他們相互的關係是對等的。本身galera cluster也是一種多主架構。galera cluster最關注的是資料的一致性,對待事物的行為時,要麼在所有節點上執行,要麼都不執行,它的實現機制決定了它對待一致性的行為非常嚴格,這也能非常完美的保證MySQL叢集的資料一致性。在PXC裡面任何一個節點都是可讀可寫的。在其他的節點一定是可以讀取到這個資料。
- 建議PXC使用PerconaServer(MYSQL的改進版,效能提升很大)
- PXC方案和Replication方案的對比
PXC任意一個節點都可以存在讀寫的方案,也就是任意一個節點都可以當讀或者當寫。同步複製。保證強一致性。
Replication方案,主從的方式,他是採用非同步的方式。
- PXC的資料強一致性
同步複製,事務在所有節點要提交都提交。要麼都不提交
- Replication弱一致性,主要master成功就成功了。返回給呼叫者。如果slave失敗,也沒辦法。因為已經告訴呼叫者成功了,呼叫者獲取查詢的時候查詢不到資訊。例如:在淘寶買個東西,付款也成功了,查詢訂單沒資訊是不是要罵娘。
環境搭建
應用 | IP地址 | 服務 | 配置 | 安裝應用 | 安裝方式 |
---|---|---|---|---|---|
docker-mysql | 192.168.66.100 | docker-mysql | 雙核 8g記憶體 | docker-mysql | docker |
(1). 虛擬機器vagrant講述安裝的步驟
(2).機器window/mac開通遠端登入root使用者下
PXC叢集安裝介紹
PXC既可以在linux系統安裝,也可以在docker上面安裝。
- 安裝映象PXC映象
- 建立內部網路的
處於安全,需要給PXC叢集例項建立Docker內部網路,都出可虛擬機器自帶的網段是172.17.0. , 這是內建的一個網段,當你建立了網路後,網段就更改為172.18.0.,
- 建立Docker 卷
一旦生成docker容器,不要在容器內儲存業務的資料,要把資料放到宿主機上,可以把宿主機的一個目錄對映到容器內,如果容器出現問題,只需要吧容器刪除,重新建立一個新的容器把目錄對映給新的容器。
之前一直有個疑問,如果直接對映目錄的吧,存在失敗的問題,現在終於知道解決方案了,直接對映docker卷就可以可以忽略這個問題了。
容器中的PXC節點對映資料目錄的解決方法
mysql pxc搭建
- 指令碼開發
新建立一個aaa資料庫 結果都可以用
哇塞就這麼簡單,成功的搭建了mysql的叢集
增加負載均衡方案
目前資料庫都是獨立的ip,在開發的時候總不能隨機連線一個資料庫吧。如果想請求,統一的口徑,這就需要搭建負載均衡了。雖然上邊已經搭建了叢集,但是不使用資料庫負載均衡,單節點處理所有請求,負載高,效能差。下圖就是一個節點很忙,其他節點很閒。
- 調整後的方案,使用Haproxy做負載均衡,請求被均勻分發到每個節點,單節點的負載低,效能好。haproxy不是資料庫,只是一個轉發器。
- 負載均衡中介軟體對比
LVS是不能在虛擬機器環境下安裝的。
- 安裝haproxy
docker-haproxy的介紹: https://hub.docker.com/_/haproxy/
- 配置檔案
- haproxy.cfg配置
登入:admin
密碼:abc123456
- 建立docker下的haproxy容器
- 進入容器後,載入配置檔案
- 在資料庫中建立一個haproxy的使用者,不需要設定密碼
- 登入haproxy網頁端
- 客戶端連線haproxy-mysql資料庫
正常的連線haproxy,傳遞增刪蓋查,其實是通過輪詢的方式。選擇mysql的節點。均勻的分發給mysql的例項。不會吧資料庫的請求都集中在一個節點上。把請求分散出去,每個資料庫例項獲取到的請求就小很多了。這就是資料庫的負載。
- 虛擬機器重啟後,發現pxc起不起來了
檢視日誌發現,node1無法啟動,輸入命令檢視docker logs node1
解決方案
高可用負載均衡方案
目前haproxy只有一個,單haproxy不具備高可用,必須冗餘設計。haproxy不能形成瓶頸。
- 虛擬IP技術
haproxy雙機互備離不開一個關鍵的技術,這個技術是虛擬IP,linux可以在一個網路卡內定義多個虛擬IP,得把這些IP地址定義到一個虛擬IP。
- 利用keepalived實現雙機熱備
定義出來一個虛擬IP,這個方案叫雙機熱備,準備2個keepalived,keepalived 就是為了搶佔虛擬IP的,誰手快誰能搶到,沒搶到的處於等待的狀態。搶到的叫做主伺服器,未搶到的叫做備伺服器。兩個keepalived之前有心跳檢測的,當備用的檢測到主服務掛了,就立馬搶佔虛擬IP。
-
Haproxy雙機熱備方案
-
安裝keepalived
keepalived必須在haproxy所在的容器之內,也可以在docker倉庫裡面下載一個haproxy-keepalived的映象。這裡直接在容器內安裝keepalived。
sources.list 新增下面的內容
- 更新apt源
- keepalived配置檔案
容器內的路徑:/etc/keepalived/keepalived.conf
- VI_1 名稱可以自定義
- state MASTER | keepalived的身份(MASTER主伺服器,BACKUP備份伺服器,不會搶佔虛擬機器ip)。如果都是主MASTER的話,就會進行互相爭搶IP,如果搶到了就是MASTER,另一個就是SLAVE。
- interface網路卡,定義一個虛擬IP定義到那個網路卡上邊。網路卡裝置的名稱。eth0是docker的虛擬網路卡,宿主機是可以訪問的。
- virtual_router_id 51 | 虛擬路由標識,MASTER和BACKUP的虛擬路由標識必須一致。標識可以是0-255。
- priority 100 | 權重。MASTER權重要高於BACKUP 數字越大優選級越高。可以根據硬體的配置來完成,權重最大的獲取搶到的級別越高。
- advert_int 1 | 心跳檢測。MASTER與BACKUP節點間同步檢查的時間間隔,單位為秒。主備之間必須一致。
- authentication | 主從伺服器驗證方式。主備必須使用相同的密碼才能正常通訊。進行心跳檢測需要登入到某個主機上邊所有有賬號密碼。
- virtual_ipaddress | 虛擬ip地址,可以設定多個虛擬ip地址,每行一個。根據上邊配置的eth0上配置的ip。
- 啟動keeplived
容器內啟動
宿主機ping這個ip
建立haproxy2容器,並配置與haproxy1相同的環境
因為要保證有2個haproxy 和keepalived,這次就不那麼麻煩了。直接對一個映象裡面包括keeplived 和 haproxy。
- 宿主機建立檔案
- haproxy.cfg
- keepalived.cfg
- docker的方式一下安裝好 haproxy 和keepalived
https://hub.docker.com/r/pelin/haproxy-keepalived/
對映埠更改為4003 4004 name修改h2
宿主機安裝keepalived
- keepalived.cof
- 啟動宿主機
虛擬機器埠轉發 外部無法訪問
- 解決方案
宿主機修改
PS:如果通過docker的方式直接拉取haproxy和keepalived映象,比直接在映象裡面安裝應用方便很多,建議各位老鐵儘量避免在容器內安裝應用,這樣真心麻煩不爽,別人封裝的映象根據pull的量好好看看api就可以使用了。像h1如果容器stop後,重新start,還需要進入容器把keeplived給起起來。而h2直接start裡面的haproxy和keeplived,同時都起起來了。 兩個容器的採用的熱備的方案,讓使用者毫無感知,切換ip的形式真是美滋滋。mysql叢集的高效能,高負載,高可用基本完成了,可用按照這個思路搭建不同的主機下。
About Me
........................................................................................................................ ● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除 ● 本文在itpub、部落格園、CSDN和個人微 信公眾號( DB寶)上有同步更新 ● 本文itpub地址: http://blog.itpub.net/26736162 ● 本文部落格園地址: http://www.cnblogs.com/lhrbest ● 本文CSDN地址: https://blog.csdn.net/lihuarongaini ● 本文pdf版、個人簡介及小麥苗雲盤地址: http://blog.itpub.net/26736162/viewspace-1624453/ ● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/ ● DBA寶典今日頭條號地址: http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826 ........................................................................................................................ ● QQ群號: 230161599 、618766405 ● 微 信群:可加我微 信,我拉大家進群,非誠勿擾 ● 聯絡我請加QQ好友 ( 646634621 ),註明新增緣由 ● 於 2020-04-01 06:00 ~ 2020-04-30 24:00 在西安完成 ● 最新修改時間:2020-04-01 06:00 ~ 2020-04-30 24:00 ● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解 ● 版權所有,歡迎分享本文,轉載請保留出處 ........................................................................................................................ ● 小麥苗的微店: https://weidian.com/s/793741433?wfr=c&ifr=shopdetail ● 小麥苗出版的資料庫類叢書: http://blog.itpub.net/26736162/viewspace-2142121/ ● 小麥苗OCP、OCM、高可用網路班: http://blog.itpub.net/26736162/viewspace-2148098/ ● 小麥苗騰訊課堂主頁: https://lhr.ke.qq.com/ ........................................................................................................................ 使用 微 信客戶端掃描下面的二維碼來關注小麥苗的微 信公眾號( DB寶)及QQ群(DBA寶典)、新增小麥苗微 信, 學習最實用的資料庫技術。
........................................................................................................................ |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2684413/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL高可用方案-PXC環境部署記錄MySql
- Docker快速部署NacosDocker
- docker部署MySQLDockerMySql
- 【Docker】使用docker部署 mysqlDockerMySql
- 快速部署-01-dockerDocker
- Docker 部署 MySQL 5.7DockerMySql
- docker快速部署DNS,實現快速上線DockerDNS
- mysql學習筆記之快速搭建PXC叢集(Mycat分片)MySql筆記
- docker部署mysql叢集DockerMySql
- 使用Docker快速部署開源商城Docker
- MySQL高可用方案-PXC(Percona XtraDB Cluster)環境部署詳解MySql
- 在MYSQL中快速建立空表薦MySql
- Asp.Net Core WebAPI+PostgreSQL部署在Docker中ASP.NETWebAPISQLDocker
- MySQL叢集搭建方案(PXC)MySql
- FastAPI(62)- FastAPI 部署在 DockerASTAPIDocker
- Docker 入門系列三:Docker 應用部署-MySQLDockerMySql
- docker 部署 django + mysql + vue 專案DockerDjangoMySqlVue
- docker部署mysql8主從DockerMySql
- SpringBoot使用Docker快速部署專案Spring BootDocker
- Docker Linux快速安裝及Nginx部署DockerLinuxNginx
- Docker 快速入門系列-Docker 在 MacOS 安裝DockerMac
- 【Docker快速入門】在Ubuntu下安裝DockerDockerUbuntu
- Docker 部署 Django+Uwsgi+Nginx+MySQL+VueDockerDjangoNginxMySqlVue
- Linux下使用docker部署mysql(一)LinuxDockerMySql
- 在 Kubernetes 中基於 StatefulSet 部署 MySQL(上)MySql
- 在 K8S 中快速部署 Redis Cluster & RedisinsightK8SRedis
- Docker升級MySQL版本的快速方法DockerMySql
- IBM /AIX 環境快速部署MySQLIBMAIMySql
- 在docker容器中部署Web專案DockerWeb
- 在docker中安裝mysql並搭建主從複製DockerMySql
- 使用Docker快速部署ELK分析Nginx日誌實踐DockerNginx
- RORedis快速部署為Docker容器的實現方法zmhRedisDocker
- docker-compose快速部署flink1.18.1Docker
- MySQL高可用架構-MMM、MHA、MGR、PXCMySql架構
- MySQL高可用架構之PXC實踐MySql架構
- MySQL Cluster開發環境快速部署(中文)MySql開發環境
- 『中級篇』在docker-swarm叢集裡透過serivce部署worDockerSwarm
- 在Docker中部署Spring Boot專案DockerSpring Boot