MySQL高可用之MGC--MariaDB Galera Cluster
MySQL高可用之MGC--MariaDB Galera Cluster
MariaDB Galera Cluster 介紹
https://cloud.tencent.com/developer/article/1120419
MariaDB 叢集是 MariaDB 同步多主機叢集。它僅支援 XtraDB/ InnoDB 儲存引擎(雖然有對 MyISAM 實驗支援 - 看 wsrep_replicate_myisam 系統變數)。
主要功能:
- 同步複製
- 真正的 multi-master,即所有節點可以同時讀寫資料庫
- 自動的節點成員控制,失效節點自動被清除
- 新節點加入資料自動複製
- 真正的並行複製,行級
- 使用者可以直接連線叢集,使用感受上與MySQL完全一致
優勢:
- 因為是多主,所以不存在Slavelag(延遲)
- 不存在丟失事務的情況
- 同時具有讀和寫的擴充套件能力
- 更小的客戶端延遲
- 節點間資料是同步的,而 Master/Slave 模式是非同步的,不同 slave 上的 binlog 可能是不同的
技術:
Galera 叢集的複製功能基於 Galeralibrary 實現,為了讓 MySQL 與 Galera library 通訊,特別針對 MySQL 開發了 wsrep API。
Galera 外掛保證叢集同步資料,保持資料的一致性,靠的就是可認證的複製,工作原理如下圖:
當客戶端發出一個 commit 的指令,在事務被提交之前,所有對資料庫的更改都會被
write-set
收集起來,並且將
write-set
紀錄的內容傳送給其他節點。
write-set
將在每個節點進行認證測試,測試結果決定著節點是否應用
write-set
更改資料。
如果認證測試失敗,節點將丟棄 write-set ;如果認證測試成功,則事務提交。
MariaDB Galera Cluster搭建
我這裡實驗時使用的作業系統是CentOS7,使用了3臺虛擬機器,IP分別為
10.211.55.6
、
10.211.55.7
、
10.211.55.8
關閉防火牆及selinux
為了先把MariaDB Galera Cluster部署起來,不受防火牆、selinux的干擾,先把3臺虛擬機器上這倆關閉了。如果防火牆一定要開啟,可參考 這裡設定防火牆規則。
systemctl disable firewalld.service systemctl stop firewalld.service setenforce 0sed -i 's/^SELINUX=.*$/SELINUX=disabled/' /etc/selinux/config
新增mariadb的yum源
在3臺虛擬機器上執行以下命令
# 已使用國內yum映象,原映象地址是http://yum.mariadb.org echo '[mariadb]name = MariaDB baseurl = http://mirrors.ustc.edu.cn/mariadb/yum/10.1/centos7-amd64 gpgkey=http://mirrors.ustc.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB gpgcheck=1' > /etc/yum.repos.d/MariaDB.repo
安裝軟體包
在3臺虛擬機器上執行以下命令
1 |
yum install -y mariadb mariadb-server mariadb-common galera rsync |
---|
資料庫初始化
在
10.211.55.6
上執行以下命令
systemctl start mariadb mysql_secure_installation # 注意這一步是有互動的,需要回答一些問題,做一些設定 systemctl stop mariadb
修改galera相關配置
在3臺虛擬機器上均開啟
/etc/my.cnf.d/server.cnf
進行編輯,修改片斷如下:
...[galera]wsrep_on=ON wsrep_provider=/usr/lib64/galera/libgalera_smm.so wsrep_cluster_name=galera_cluster wsrep_cluster_address="gcomm://10.211.55.6,10.211.55.7,10.211.55.8"wsrep_node_name=10.211.55.6 # 注意這裡改成本機IP wsrep_node_address=10.211.55.6 # 注意這裡改成本機IP binlog_format=row default_storage_engine=InnoDB innodb_autoinc_lock_mode=2...
啟動MariaDB Galera Cluster服務
先在第1臺虛擬機器執行以下命令:
sudo -u mysql /usr/sbin/mysqld --wsrep-new-cluster &> /tmp/wsrep_new_cluster.log &disown $!tail -f /tmp/wsrep_new_cluster.log
出現
ready for connections
,證明啟動成功,繼續在另外兩個虛擬機器裡執行命令:
1 |
systemctl start mariadb |
---|
等後面兩個虛擬機器裡mariadb服務啟動後,再到第1臺虛擬機器裡執行以下命令:
(ps -ef|grep mysqld|grep -v grep|awk '{print $2}'|xargs kill -9) &>/dev/nullsystemctl start mariadb
驗證MariaDB Galera Cluster服務
在任意虛擬機器裡執行以下命令:
mysql -e "show status like 'wsrep_cluster_size'" # 這裡應該顯示叢集裡有3個節點 mysql -e "show status like 'wsrep_connected'" # 這裡應該顯示ON mysql -e "show status like 'wsrep_incoming_addresses'" # 這裡應該顯示10.211.55.7:3306,10.211.55.8:3306,10.211.55.6:3306mysql -e "show status like 'wsrep_local_state_comment'" # 這裡節點的同步狀態
檢視叢集全部相關狀態引數可執行以下命令:
1 |
mysql -e "show status like 'wsrep_%'" |
---|
至此,MariaDB Galera Cluster已經成功部署。
MariaDB Galera Cluster的自啟動
在實際使用中發現一個問題,Galera叢集啟動時必須按照一個特定的規則啟動,研究了下,發現規則如下:
- 如果叢集從來沒有啟動過(3個節點上都沒有
/var/lib/mysql/grastate.dat
檔案),則必要由其中一個節點以--wsrep-new-cluster
引數啟動,另外兩個節點正常啟動即可 - 如果叢集以前啟動過,則參考
/var/lib/mysql/grastate.dat
,找到safe_to_bootstrap
為1
的節點,在該節點上以--wsrep-new-cluster
引數啟動,另外兩個節點正常啟動即可 - 如果叢集以前啟動過,但參考
/var/lib/mysql/grastate.dat
,找不到safe_to_bootstrap
為1
的節點(一般是因為mariadb服務非正常停止造成),則在3個節點中隨便找1個節點,將/var/lib/mysql/grastate.dat
中的safe_to_bootstrap
修改為1,再在該節點上以--wsrep-new-cluster
引數啟動,另外兩個節點正常啟動即可
從以上3種場景可知,正常情況下很難保證mariadb galera cluster可以無人值守地完成開機自啟動。國外論壇上也有人反映了 這個問題,但好像官方的人員好像說設計上就是這樣,怎麼可以這樣。。。
最後寫了個指令碼,放在3個虛擬機器上面,解決了這個問題。指令碼如下:
cat /usr/local/bin/mariadb_cluster_helper.sh #!/bin/bash GRASTATE_FILE=/var/lib/mysql/grastate.dat WSREP_NEW_CLUSTER_LOG_FILE=/tmp/wsrep_new_cluster.log # 如果啟動mariadb超過10秒還沒返回0,則認為失敗了 START_MARIADB_TIMEOUT=10# 以--wsrep-new-cluster引數啟動,超過5次檢查,發現仍沒有其它節點加入叢集,則認為此路不通 SPECIAL_START_WAIT_MAX_COUNT=5# 得到本機IP MY_IP=$(grep 'wsrep_node_address' /etc/my.cnf.d/server.cnf | awk -F '=' '{print $2}')# 殺掉mysqld程式function kill_mysqld_process() { (ps -ef|grep mysqld|grep -v grep|awk '{print $2}'|xargs kill -9) &>/dev/null}# 正常啟動mariadbfunction start_mariadb_normal(){ # 首先確保safe_to_bootstrap標記為0 sed -i 's/^safe_to_bootstrap.*$/safe_to_bootstrap: 0/' $GRASTATE_FILE timeout $START_MARIADB_TIMEOUT systemctl start mariadb &> /dev/null return $?}# 以--wsrep-new-cluster引數啟動mariadbfunction start_mariadb_special(){ # 首先確保safe_to_bootstrap標記為1 sed -i 's/^safe_to_bootstrap.*$/safe_to_bootstrap: 1/' $GRASTATE_FILE # 以--wsrep-new-cluster引數啟動mariadb /usr/sbin/mysqld --user=mysql --wsrep-new-cluster &> $WSREP_NEW_CLUSTER_LOG_FILE & disown $! try_count=0 # 迴圈檢查 while [ 1 ]; do # 如果超過SPECIAL_START_WAIT_MAX_COUNT次檢查,仍沒有其它節點加入叢集,則認為此路不通,嘗試正常啟動,跳出迴圈 if [ $try_count -gt $SPECIAL_START_WAIT_MAX_COUNT ] ; then kill_mysqld_process start_mariadb_normal return $? fi new_joined_count=$(grep 'synced with group' /tmp/wsrep_new_cluster.log | grep -v $MY_IP|wc -l) exception_count=$(grep 'exception from gcomm, backend must be restarted' $WSREP_NEW_CLUSTER_LOG_FILE | wc -l) # 如果新加入的節點數大於0,則認為叢集就緒了,可正常啟動了,跳出迴圈 # 如果執行日誌中發現了異常(兩個節點都以--wsrep-new-cluster引數啟動,其中一個會報錯),則認為此路不通,嘗試正常啟動,跳出迴圈 if [ $new_joined_count -gt 0 ] || [ $exception_count -gt 0 ] ; then kill_mysqld_process start_mariadb_normal return $? else try_count=$(( $try_count + 1 )) fi sleep 5 done}# 首先殺掉mysqld程式 kill_mysqld_process ret=-1# 如果safe_to_bootstrap標記為1,則立即以--wsrep-new-cluster引數啟動if [ -f $GRASTATE_FILE ]; then safe_bootstrap_flag=$(grep 'safe_to_bootstrap' $GRASTATE_FILE | awk -F ': ' '{print $2}') if [ $safe_bootstrap_flag -eq 1 ] ; then start_mariadb_special ret=$? else start_mariadb_normal ret=$? fielse start_mariadb_normal ret=$?fi # 隨機地按某種方式啟動,直到以某種方式正常啟動以止;否則殺掉mysqld程式,隨機休息一會兒,重試while [ $ret -ne 0 ]; do kill_mysqld_process sleep_time=$(( $RANDOM % 10 )) sleep $sleep_time choice=$(( $RANDOM % 2 )) ret=-1 if [ $choice -eq 0 ] ; then start_mariadb_special ret=$? else start_mariadb_normal ret=$? fi done # 使上述指令碼開機自啟動 chmod +x /usr/local/bin/mariadb_cluster_helper.sh chmod +x /etc/rc.d/rc.local echo '/usr/local/bin/mariadb_cluster_helper.sh &> /var/log/mariadb_cluster_helper.log &' >> /etc/rc.d/rc.local
然後3個節點終於可以開機自啟動自動組成叢集了。
搭配keepalived+haproxy+clustercheck
為了保證mariadb galera叢集的高可用,可以使用haproxy進行請求 負載均衡,同時為了實現haproxy的高可用,可使用keepalived實現haproxy的熱備方案。keepalived實現haproxy的熱備方案可參見之前的 博文。這裡重點說一下haproxy對mariadb galera叢集的請求負載均衡。
這裡使用了 https://github.com/olafz/percona-clustercheck 所述方案,使用外部指令碼在應用層檢查galera節點的狀態。
首先在mariadb裡進行授權:
1 |
GRANT PROCESS ON *.* TO 'clustercheckuser'@'%' IDENTIFIED BY 'clustercheckpassword!' |
---|
下載檢測指令碼:
wget -O /usr/bin/clustercheck https://raw.githubusercontent.com/olafz/percona-clustercheck/master/clustercheck chmod +x /usr/bin/clustercheck
準備檢測指令碼用到的配置檔案:
MYSQL_USERNAME="clustercheckuser"MYSQL_PASSWORD="clustercheckpassword!"MYSQL_HOST="$db_ip"MYSQL_PORT="3306"AVAILABLE_WHEN_DONOR=0
測試一下監控指令碼:
# /usr/bin/clustercheck > /dev/null# echo $?0 # synced1 # un-synced
使用xinetd暴露http介面,用於檢測galera節點同步狀態:
cat > /etc/xinetd.d/mysqlchk << EOF # default: on # description: mysqlchk service mysqlchk{ disable = no flags = REUSE socket_type = stream port = 9200 wait = no user = nobody server = /usr/bin/clustercheck log_on_failure += USERID only_from = 0.0.0.0/0 per_source = UNLIMITED}EOF service xinetd restart
測試一下暴露出的http介面:
curl http://127.0.0.1:9200Galera cluster node is synced. # synced Galera cluster node is not synced # un-synced
最後在
/etc/haproxy/haproxy.cfg
裡配置負載均衡:
...frontend vip-mysql bind $vip:3306 timeout client 900m log global option tcplog mode tcp default_backend vms-mysql backend vms-mysql option httpchk stick-table type ip size 1000 stick on dst balance leastconn timeout server 900m server mysql1 $db1_ip:3306 check inter 1s port 9200 backup on-marked-down shutdown-sessions maxconn 60000 server mysql2 $db2_ip:3306 check inter 1s port 9200 backup on-marked-down shutdown-sessions maxconn 60000 server mysql2 $db3_ip:3306 check inter 1s port 9200 backup on-marked-down shutdown-sessions maxconn 60000...
搭配galera仲裁服務
官方也提到gelera叢集最少要三節點部署,但每增加一個節點,要付出相應的資源,因此也可以最少兩節點部署,再加上一個galera仲裁服務。
The recommended deployment of Galera Cluster is that you use a minimum of three instances. Three nodes, three datacenters and so on. In the event that the expense of adding resources, such as a third datacenter, is too costly, you can use Galera Arbitrator. Galera Arbitrator is a member of the cluster that participates in voting, but not in the actual replication
這種部署模式有兩個好處:
- 使叢集剛好是奇數節點,不易產生腦裂。
- 可能通過它得到一個一致的資料庫狀態快照,可以用來備份。
這種部署模式的架構圖如下:
mage-20180401214224
部署方法也比較簡單:
# 假設已經構建了一個兩節點的galera叢集,在第3個節點部署garbd服務 echo ' GALERA_NODES="10.211.55.6:4567 10.211.55.7:4567" # 這裡是兩節點的地址 GALERA_GROUP="galera_cluster" # 這裡的group名稱保持與兩節點的wsrep_cluster_name屬性一致 LOG_FILE="/var/log/garb.log"' > /etc/sysconfig/garb systemctl start garb # 啟動garbd服務
測試一下效果。
首先看一下兩節點部署產生腦裂的場景。
# 首先在第3個節點停止garb服務 systemctl stop garb # 然後在第2個節點drop掉去住第1個節點和仲裁節點的資料包 iptables -A OUTPUT -d 10.211.55.6 -j DROP iptables -A OUTPUT -d 10.211.55.9 -j DROP # 這時檢查前兩個節點的同步狀態,發生腦裂了,都不是同步狀態了 mysql -e "show status like 'wsrep_local_state_comment'"+---------------------------+-------------+| Variable_name | Value |+---------------------------+-------------+| wsrep_local_state_comment | Initialized |+---------------------------+-------------+
再試驗下有仲裁節點參與的場景。
# 首先在第3個節點啟動garb服務 systemctl start garb # 在前兩個節點檢視叢集節點數,發現是3個,說明包括了仲裁節點 mysql -e "show status like 'wsrep_cluster_size'"+---------------------------+-------------+| Variable_name | Value |+---------------------------+-------------+| wsrep_cluster_size | 3 |+---------------------------+-------------+# 然後在第2個節點drop掉去住第1個節點和仲裁節點的資料包 iptables -A OUTPUT -d 10.211.55.6 -j DROP iptables -A OUTPUT -d 10.211.55.9 -j DROP # 這時檢查第1個節點的同步狀態,仍然是同步狀態 mysql -e "show status like 'wsrep_local_state_comment'"+---------------------------+-------------+| Variable_name | Value |+---------------------------+-------------+| wsrep_local_state_comment | Synced |+---------------------------+-------------+# 再在第1個節點檢視叢集節點數,發現是2個 mysql -e "show status like 'wsrep_cluster_size'"+---------------------------+-------------+| Variable_name | Value |+---------------------------+-------------+| wsrep_cluster_size | 2 |+---------------------------+-------------+# 這時檢查第2個節點的同步狀態,發現是未同步的 mysql -e "show status like 'wsrep_local_state_comment'"+---------------------------+-------------+| Variable_name | Value |+---------------------------+-------------+| wsrep_local_state_comment | Initialized |+---------------------------+-------------+
以前試驗說明採用了仲裁節點後,因為叢集節點數變為了奇數,有效地避免了腦裂,同時將真正有故障的節點隔離出去了。
參考
- https://segmentfault.com/a/1190000002955693
- https://github.com/olafz/percona-clustercheck
- http://galeracluster.com/documentation-webpages/arbitrator.html
About Me
........................................................................................................................ ● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除 ● 本文在itpub、部落格園、CSDN和個人微 信公眾號( xiaomaimiaolhr)上有同步更新 ● 本文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-02-01 06:00 ~ 2020-02-31 24:00 在西安完成 ● 最新修改時間:2020-02-01 06:00 ~ 2020-02-31 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/ ........................................................................................................................ 使用 微 信客戶端掃描下面的二維碼來關注小麥苗的微 信公眾號( xiaomaimiaolhr)及QQ群(DBA寶典)、新增小麥苗微 信, 學習最實用的資料庫技術。
........................................................................................................................ |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2676352/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL高可用之GC-Galera Cluster for MySQLMySqlGC
- 9. MySQL Galera Cluster全解析 Part 9 監控Galera ClusterMySql
- 7. MySQL Galera Cluster全解析 Part 7 Galera Cluster部署指南MySql
- 1. MySQL Galera Cluster全解析 Part 1 Galera Cluster 簡介MySql
- MySQL Galera Cluster全解析 Part 4 Galera Cluster 安裝前準備MySql
- 6. MySQL Galera Cluster全解析 Part 6 Galera Cluster引數設定MySql
- 5. MySQL Galera Cluster全解析 Part 5 Galera Cluster軟體安裝MySql
- 8. MySQL Galera Cluster全解析 Part 8 Galera Cluster和傳統MySQL的不同點MySql
- 基於Centos7.x 搭建MySQL Galera Cluster高可用架構CentOSMySql架構
- MySQL Galera cluster叢集常用引數說明MySql
- MySQL Galera Cluster全解析 Part 3 狀態快照傳輸(SST)MySql
- mysql高可用之keepalivedMySql
- 10. MySQL Galera Cluster全解析 Part 10 grastate.dat檔案詳解MySqlAST
- 2. MySQL Galera Cluster全解析 Part 2 基於認證的複製MySql
- MySQL ClusterMySql
- MySQL高可用之MHA切換測試(switchover & failover)MySqlAI
- 【DB寶19】MySQL高可用之MHA功能測試MySql
- 【DB寶19】在Docker中使用MySQL高可用之MHADockerMySql
- 【DB寶45】MySQL高可用之MGR+Consul架構部署MySql架構
- MySQL高可用方案-PXC(Percona XtraDB Cluster)環境部署詳解MySql
- 【DB寶18】在Docker中安裝使用MySQL高可用之MGRDockerMySql
- 高可用之KeepAlive工作原理
- 基於MySQL Cluster + LVS + KeepAlived部署負載均衡高可用架構MySql負載架構
- 面試官:你如何利用 MySQL Cluster 實現整體高可用?面試MySql
- RabbitMQ 高可用之映象佇列MQ佇列
- Mysql-cluster小專案MySql
- opengauss高可用之keepalived配置 原創
- 高可用之戰:Redis Sentinal(哨兵模式)Redis模式
- Markdown高階使用之流程圖流程圖
- MySQL高可用之組複製技術(3):配置多主模型的組複製MySql模型
- MySQL高可用之組複製技術(2):配置單主模型的組複製MySql模型
- 藉助 TCP 負載均衡和 Galera 叢集擴充套件 MySQLTCP負載套件MySql
- Redis高可用之戰:主從架構Redis架構
- 高可用之限流-01-入門介紹
- postgresql高階應用之合併單元格SQL
- MySQL InnoDB Cluster – how to manage a split-brain situationMySqlAI
- 技術分享 | MySQL InnoDB Cluster Set 介紹MySql
- Spring Cloud Eureka Server高可用之:線上擴容SpringCloudServer