MySQL高可用方案-PXC環境部署記錄

 

以前梳理了Mysql+Keepalived雙主熱備高可用操做記錄,對於mysql高可用方案,常常用到的的主要有下面三種:html

1、基於主從複製的高可用方案:雙節點主從 + keepalivednode

通常來講,中小型規模的時候,採用這種架構是最省事的。
兩個節點能夠採用簡單的一主一從模式,或者雙主模式,而且放置於同一個VLAN中,在master節點發生故障後,利用keepalived/heartbeat的高可用機制實現快速
切換到slave節點。
 
在這個方案裏,有幾個須要注意的地方:
採用keepalived做爲高可用方案時,兩個節點最好都設置成BACKUP模式,避免由於意外狀況下(好比腦裂)相互搶佔致使往兩個節點寫入相同數據而引起衝突;
1)把兩個節點的auto_increment_increment(自增步長)和auto_increment_offset(自增起始值)設成不一樣值。其目的是爲了不master節點意外宕機時,
可能會有部分binlog未能及時複製到slave上被應用,從而會致使slave新寫入數據的自增值和原先master上衝突了,所以一開始就使其錯開;固然了,若是有合適的
容錯機制能解決主從自增ID衝突的話,也能夠不這麼作;
2)slave節點服務器配置不要太差,不然更容易致使複製延遲。做爲熱備節點的slave服務器,硬件配置不能低於master節點;
3)若是對延遲問題很敏感的話,可考慮使用MariaDB分支版本,或者直接上線MySQL 5.7最新版本,利用多線程複製的方式能夠很大程度下降複製延遲;
4)對複製延遲特別敏感的另外一個備選方案,是採用semi sync replication(就是所謂的半同步複製)或者後面會提到的PXC方案,基本上無延遲,不過事務併發性
能會有不小程度的損失,須要綜合評估再決定;
5)keepalived的檢測機制須要適當完善,不能僅僅只是檢查mysqld進程是否存活,或者MySQL服務端口是否可通,還應該進一步作數據寫入或者運算的探測,判斷響
應時間,若是超過設定的閾值,就能夠啓動切換機制;
6)keepalived最終肯定進行切換時,還須要判斷slave的延遲程度。須要事先定好規則,以便決定在延遲狀況下,採起直接切換或等待何種策略。直接切換可能由於復
制延遲有些數據沒法查詢到而重複寫入;
7)keepalived或heartbeat自身都沒法解決腦裂的問題,所以在進行服務異常判斷時,能夠調整判斷腳本,經過對第三方節點補充檢測來決定是否進行切換,可下降腦
裂問題產生的風險。

雙節點主從+keepalived/heartbeat方案架構示意圖見下:mysql

2、基於主從複製的高可用方案:多節點主從+MHA/MMMlinux

多節點主從,能夠採用一主多從,或者雙主多從的模式。
這種模式下,能夠採用MHA或MMM來管理整個集羣,目前MHA應用的最多,優先推薦MHA,最新的MHA也已支持MySQL 5.6的GTID模式了,是個好消息。

MHA的優點很明顯:
1)開源,用Perl開發,代碼結構清晰,二次開發容易;
2)方案成熟,故障切換時,MHA會作到較嚴格的判斷,儘可能減小數據丟失,保證數據一致性;
3)提供一個通用框架,可根據本身的狀況作自定義開發,尤爲是判斷和切換操做步驟;
4)支持binlog server,可提升binlog傳送效率,進一步減小數據丟失風險。

不過MHA也有些限制:
1)須要在各個節點間打通ssh信任,這對某些公司安全制度來講是個挑戰,由於若是某個節點被黑客攻破的話,其餘節點也會跟着遭殃;
2)自帶提供的腳本還須要進一步補充完善,固然了,通常的使用仍是夠用的。

3、基於Galera協議的高可用方案:PXC sql

Galera是Codership提供的多主數據同步複製機制,能夠實現多個節點間的數據同步複製以及讀寫,而且可保障數據庫的服務高可用及數據一致性。
基於Galera的高可用方案主要有MariaDB Galera Cluster和Percona XtraDB Cluster(簡稱PXC),目前PXC用的會比較多一些。
mariadb的集羣原理跟PXC同樣,maridb-cluster其實就是PXC,二者原理是同樣的。

下面重點介紹下基於PXC的mysql高可用環境部署記錄。數據庫

一、PXC介紹bootstrap

Percona XtraDB Cluster(簡稱PXC集羣)提供了MySQL高可用的一種實現方法。
1)集羣是有節點組成的,推薦配置至少3個節點,可是也能夠運行在2個節點上。
2)每一個節點都是普通的mysql/percona服務器,能夠將現有的數據庫服務器組成集羣,反之,也能夠將集羣拆分紅單獨的服務器。
3)每一個節點都包含完整的數據副本。

PXC集羣主要由兩部分組成:Percona Server with XtraDB和Write Set Replication patches(使用了Galera library,一個通用的用於事務型應用的同步、多主複製插件)。

二、PXC特性centos

1)同步複製,事務要麼在全部節點提交或不提交。
2)多主複製,能夠在任意節點進行寫操做。
3)在從服務器上並行應用事件,真正意義上的並行複製。
4)節點自動配置,數據一致性,再也不是異步複製。

PXC最大的優點:強一致性、無同步延遲

三、PXC優缺點安全

PXC的優勢
1)服務高可用;
2)數據同步複製(併發複製),幾乎無延遲;
3)多個可同時讀寫節點,可實現寫擴展,不過最好事先進行分庫分表,讓各個節點分別寫不一樣的表或者庫,避免讓galera解決數據衝突;
4)新節點能夠自動部署,部署操做簡單;
5)數據嚴格一致性,尤爲適合電商類應用;
6)徹底兼容MySQL;

雖然PXC有這麼多好處,但也有些侷限性:
1)只支持InnoDB引擎;當前版本(5.6.20)的複製只支持InnoDB引擎,其餘存儲引擎的更改不復制。然而,DDL(Data Definition Language) 語句在statement級別
被複制,而且,對mysql.*表的更改會基於此被複制。例如CREATE USER...語句會被複制,可是 INSERT INTO mysql.user...語句則不會。
(也能夠經過wsrep_replicate_myisam參數開啓myisam引擎的複製,但這是一個實驗性的參數)。
2)PXC集羣一致性控制機制,事有可能被終止,緣由以下:集羣容許在兩個節點上同時執行操做同一行的兩個事務,可是隻有一個能執行成功,另外一個會被終止,集羣會給被終止的
客戶端返回死鎖錯誤(Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)).
3)寫入效率取決於節點中最弱的一臺,由於PXC集羣採用的是強一致性原則,一個更改操做在全部節點都成功纔算執行成功。
4)全部表都要有主鍵;
5)不支持LOCK TABLE等顯式鎖操做;
6)鎖衝突、死鎖問題相對更多;
7)不支持XA;
8)集羣吞吐量/性能取決於短板;
9)新加入節點採用SST時代價高;
10)存在寫擴大問題;
11)若是併發事務量很大的話,建議採用InfiniBand網絡,下降網絡延遲;

事實上,採用PXC的主要目的是解決數據的一致性問題,高可用是順帶實現的。由於PXC存在寫擴大以及短板效應,併發效率會有較大損失,相似semi sync replication機制。

四、PXC原理描述bash

分佈式系統的CAP理論:
C:一致性,全部的節點數據一致
A:可用性,一個或者多個節點失效,不影響服務請求
P:分區容忍性,節點間的鏈接失效,仍然能夠處理請求
其實,任何一個分佈式系統,須要知足這三個中的兩個。

PXC會使用大概是4個端口號
3306:數據庫對外服務的端口號
4444:請求SST SST: 指數據一個鏡象傳輸 xtrabackup , rsync ,mysqldump 
4567: 組成員之間進行溝通的一個端口號
4568: 傳輸IST用的。相對於SST來講的一個增量。

一些名詞介紹:
WS:write set 寫數據集
IST: Incremental State Transfer 增量同步
SST:State Snapshot Transfer 全量同步 

PXC環境所涉及的端口:
#mysql實例端口
10Regular MySQL port, default 3306.   

#pxc cluster相互通信的端口
2)Port for group communication, default 4567. It can be changed by the option:  
   wsrep_provider_options ="gmcast.listen_addr=tcp://0.0.0.0:4010; "

#用於SST傳送的端口
3)Port for State Transfer, default 4444. It can be changed by the option:  
   wsrep_sst_receive_address=10.11.12.205:5555

#用於IST傳送的端口
4)Port for Incremental State Transfer, default port for group communication + 1 (4568). It can be changed by the option:  
   wsrep_provider_options = "ist.recv_addr=10.11.12.206:7777; "

PXC的架構示意圖: 

數據讀寫示意圖

---------------------------------------下面看下傳統複製流程----------------------------------

異步複製

半同步 超過10秒的閥值會退化爲異步

無論同步或是半同步,都存在必定的延遲,那麼PXC怎麼作到不延遲呢?
PXC最大的優點:強一致性、無同步延遲
每個節點均可以讀寫,WriteSet寫的集合,用箱子推給Group裏全部的成員, data page 至關於物理複製,而不是發日誌,就是一個寫的結果了。

PXC原理圖

從上圖能夠看出:
當client端執行dml操做時,將操做發給server,server的native進程處理請求,client端執行commit,server將複製寫數據集發給group(cluster),cluster
中每一個動做對應一個GTID,其它server接收到並經過驗證(合併數據)後,執行appyl_cb動做和commit_cb動做,若驗證沒經過,則會退出處理;當前server節點驗證通
事後,執行commit_cb,並返回,若沒經過,執行rollback_cb。

只要當前節點執行了commit_cb和其它節點驗證經過後就可返回。
3306:數據庫對外服務的端口號
4444:請求SST,在新節點加入時起做用
4567:組成員之間溝通的端口
4568:傳輸IST,節點下線,重啓加入時起做用
SST:全量同步
IST:增量同步 

問題:若是主節點寫入過大,apply_cb時間跟不上,怎麼處理? 
Wsrep_slave_threads參數配置成cpu的個數相等或是1.5倍。

用戶發起Commit,在收到Ok以前,集羣每次發起一個動做,都會有一個惟一的編號 ,也就是PXC獨有的Global Trx Id。
動做發起者是commit_cb,其它節點多了一個動做: apply_cb

上面的這些動做,是經過那個端號交互的?
4567,4568端口,IST只是在節點下線,重啓加入那一個時間有用
4444端口,只會在新節點加入進來時起做用

PXC結構裏面,若是主節點寫入過大,apply_cb 時間會不會跟不上,那麼wsrep_slave_threads參數 解決apply_cb跟不上問題 配置成和CPU的個數相等或是1.5倍
當前節點commit_cb 後就能夠返回了,推過去以後,驗證經過就好了能夠返回客戶端了,cb也就是commit block 提交數據塊.

五、PXC啓動和關閉過程 

State Snapshot Transfer(SST),每一個節點都有一份獨立的數據,當用mysql bootstrap-pxc啓動第一個節點,在第一個節點上把賬號初始化,其它節點啓動後加入進來。集羣中有哪些節點是由wsrep_cluster_address = gcomm://xxxx,,xxxx,xxx參數決定。第一個節點把本身備份一下(snapshot)傳給加入的新節點,第三個節點的死活是由前兩個節點投票決定。

狀態機變化階段:
1)OPEN: 節點啓動成功,嘗試鏈接到集羣,若是失敗則根據配置退出或建立新的集羣
2)PRIMARY: 節點處於集羣PC中,嘗試從集羣中選取donor進行數據同步
3)JOINER: 節點處於等待接收/接收數據文件狀態,數據傳輸完成後在本地加載數據
4)JOINED: 節點完成數據同步工做,嘗試保持和集羣進度一致
5)SYNCED:節點正常提供服務:數據的讀寫,集羣數據的同步,新加入節點的sst請求
6)DONOR(貢獻數據者):節點處於爲新節點準備或傳輸集羣全量數據狀態,對客戶端不可用。

狀態機變化因素:
1)新節點加入集羣
2)節點故障恢復
3)節點同步失效 

傳輸SST有幾種方法:
1)mysqldump
2)xtrabackup
3)rsync

好比有三個節點:node一、node二、node3
當node3停機重啓後,經過IST來同步增量數據,來完成保證與node1和node2的數據一致,IST的實現是由wsrep_provider_options="gcache.size=1G"參數決定,
通常設置爲1G大,參數大小是由什麼決定的,根據停機時間,若停機一小時,須要確認1小時內產生多大的binlog來算出參數大小。
假設這三個節點都關閉了,會發生什麼呢?
所有傳SST,由於gcache數據沒了
所有關閉須要採用滾動關閉方式:
1)關閉node1,修復完後,啓動加回來;
2)關閉node2,修復完後,啓動加回來;
3)......,直到最後一個節點
4)原則要保持Group裏最少一個成員活着
 
數據庫關閉以後,最會保存一個last Txid,因此啓動時,先要啓動最後一個關閉的節點,啓動順序和關閉順序恰好相反。
wsrep_recover=on參數在啓動時加入,用於從log中分析gtid。
怎樣避免關閉和啓動時數據丟失?
1)全部的節點中最少有一個在線,進行滾動重啓;
2)利用主從的概念,把一個從節點轉化成PXC裏的節點。

六、PXC注意的問題

1)腦裂:任何命令執行出現unkown command ,表示出現腦裂,集羣兩節點間4567端口連不通,沒法提供對外服務。
   SET GLOBAL wsrep_provider_options="pc.ignore_sb=true"; 
2)併發寫:三個節點的自增起始值爲一、二、3,步長都爲3,解決了insert問題,但update同時對一行操做就會有問題,出現:
   Error: 1213  SQLSTATE: 40001,因此更新和寫入在一個節點上操做。
3)DDL:引發全局鎖,採用:pt-online-schema-change 
4)MyISAM引擎不能被複制,只支持innodb
5)pxc結構裏面必須有主鍵,若是沒有主建,有可能會形成集中每一個節點的Data page裏的數據不同
6)不支持表級鎖,不支持lock /unlock tables 
7)pxc裏只能把slow log ,query log 放到File裏
8)不支持XA事務
9)性能由集羣中性能最差的節點決定

------------------------------------------------------------------------------------------------------------
下面記錄在Centos下部署基於PXC的Mysql高可用方案操做過程

官方配置說明:https://www.percona.com/doc/percona-xtradb-cluster/5.5/howtos/centos_howto.html

1)環境描述(centos6.8版本)
node1  10.171.60.171  percona1
node2  10.44.183.73   percona2
node3  10.51.58.169   percona3
  
三個節點上的iptables最好關閉(不然就要開放330六、444四、456七、4568端口的訪問)、關閉selinux
  
2)三個node節點都要執行如下操做。
能夠選擇源碼或者yum,在此使用yum安裝。
基礎安裝
[root@percona1 ~]# yum -y groupinstall Base Compatibility libraries Debugging Tools Dial-up Networking suppport Hardware monitoring utilities Performance Tools Development tools
  
組件安裝
[root@percona1 ~]# yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm -y
[root@percona1 ~]# yum install Percona-XtraDB-Cluster-55 -y
  
3)數據庫配置
選擇一個node做爲名義上的master,下面就以node1爲master,只須要修改mysql的配置文件--/etc/my.cnf
  
----------------如下是在node1節點上的配置----------------------
[root@percona1 ~]# cat /etc/my.cnf
[mysqld]
  
datadir=/var/lib/mysql
user=mysql
  
# Path to Galera library
wsrep_provider=/usr/lib64/libgalera_smm.so
  
# Cluster connection URL contains the IPs of node#1, node#2 and node#3
wsrep_cluster_address=gcomm://10.171.60.171,10.44.183.73,10.51.58.169
  
# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW
  
# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB
  
# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2
  
# Node #1 address
wsrep_node_address=10.171.60.171
  
# SST method
wsrep_sst_method=xtrabackup-v2
  
# Cluster name
wsrep_cluster_name=my_centos_cluster
  
# Authentication for SST method
wsrep_sst_auth="sstuser:s3cret"
  
啓動數據庫(三個節點都要操做):
node1的啓動方式:
[root@percona1 ~]# /etc/init.d/mysql bootstrap-pxc
.....................................................................
若是是centos7,則啓動命令以下:
[root@percona1 ~]# systemctl start mysql@bootstrap.service
.....................................................................
如果重啓的話,就先kill,而後刪除pid文件後再執行上面的啓動命令。
  
配置數據庫(三個節點都要操做)
mysql> show status like 'wsrep%';
+----------------------------+--------------------------------------+
| Variable_name              | Value                                |
+----------------------------+--------------------------------------+
.........
| wsrep_local_state          | 4                                    |
| wsrep_local_state_comment  | Synced                               |
| wsrep_cert_index_size      | 0                                    |
| wsrep_causal_reads         | 0                                    |
| wsrep_incoming_addresses   | 10.171.60.171:3306                   |      //集羣中目前只有一個成員的ip
| wsrep_cluster_conf_id      | 1                                    |
| wsrep_cluster_size         | 1                                    |      //主要看這裏,目前node2和node3尚未加入集羣,因此集羣成員目前只有一個
| wsrep_cluster_state_uuid   | 5dee8d6d-455f-11e7-afd8-ca25b704d994 |
| 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     | 2.12(r318911d)                       |
| wsrep_ready                | ON                                   |
| wsrep_thread_count         | 2                                    |
+----------------------------+--------------------------------------+
  
數據庫用戶名密碼的設置
mysql> UPDATE mysql.user SET password=PASSWORD("Passw0rd") where user='root';
  
建立、受權、同步帳號
mysql> CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 's3cret';
mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'sstuser'@'localhost';
mysql> FLUSH PRIVILEGES;
  
................注意下面幾個察看命令...............
mysql> SHOW VARIABLES LIKE 'wsrep_cluster_address';
#若是配置了指向集羣地址,上面那個參數值,應該是你指定集羣的IP地址
  
# 此參數查看是否開啓
mysql> show status like 'wsrep_ready';
  
# 查看集羣的成員數
mysql> show status like 'wsrep_cluster_size';
  
# 這個查看wsrep的相關參數
mysql> show status like 'wsrep%';
  
4)那麼node2和node3只須要配置my.cnf文件中的wsrep_node_address這個參數,將其修改成本身的ip地址便可。
------------------------------------
node2節點的/etc/my.cnf配置
[root@percona2 ~]# cat /etc/my.cnf
[mysqld]
  
datadir=/var/lib/mysql
user=mysql
  
# Path to Galera library
wsrep_provider=/usr/lib64/libgalera_smm.so
  
# Cluster connection URL contains the IPs of node#1, node#2 and node#3
wsrep_cluster_address=gcomm://10.171.60.171,10.44.183.73,10.51.58.169
  
# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW
  
# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB
  
# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2
  
# Node #1 address
wsrep_node_address=10.44.183.73
  
# SST method
wsrep_sst_method=xtrabackup-v2
  
# Cluster name
wsrep_cluster_name=my_centos_cluster
  
# Authentication for SST method
wsrep_sst_auth="sstuser:s3cret"
  
----------------------------------
node3節點的/etc/my.cnf配置
[root@percona3 ~]# cat /etc/my.cnf
[mysqld]
  
datadir=/var/lib/mysql
user=mysql
  
# Path to Galera library
wsrep_provider=/usr/lib64/libgalera_smm.so
  
# Cluster connection URL contains the IPs of node#1, node#2 and node#3
wsrep_cluster_address=gcomm://10.171.60.171,10.44.183.73,10.51.58.169
  
# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW
  
# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB
  
# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2
  
# Node #1 address
wsrep_node_address=10.51.58.169
  
# SST method
wsrep_sst_method=xtrabackup-v2
  
# Cluster name
wsrep_cluster_name=my_centos_cluster
  
# Authentication for SST method
wsrep_sst_auth="sstuser:s3cret"
  
node2和node3的啓動方式:
[root@percona2 ~]# /etc/init.d/mysql start

..................................注意................................ 
-> 除了名義上的master以外,其它的node節點只須要啓動mysql便可。
-> 節點的數據庫的登錄和master節點的用戶名密碼一致,自動同步。因此其它的節點數據庫用戶名密碼無須從新設置。
   也就是說,如上設置,只須要在名義上的master節點(如上的node1)上設置權限,其它的節點配置好/etc/my.cnf後,只須要啓動mysql就行,權限會自動同步過來。
   如上的node2,node3節點,登錄mysql的權限是和node1同樣的(便是用node1設置的權限登錄)
.....................................................................

若是上面的node二、node3啓動mysql失敗,好比/var/lib/mysql下的err日誌報錯以下:
[ERROR] WSREP: gcs/src/gcs_group.cpp:long int gcs_group_handle_join_msg(gcs_

解決辦法:
-> 查看節點上的iptables防火牆是否關閉;檢查到名義上的master節點上的4567端口是否連通(telnet)
-> selinux是否關閉
-> 刪除名義上的master節點上的grastate.dat後,重啓名義上的master節點的數據庫;固然當前節點上的grastate.dat也刪除並重啓數據庫
.....................................................................
  
5)最後進行測試
在任意一個node上,進行添加,刪除,修改操做,都會同步到其餘的服務器,是如今主主的模式,固然前提是表引擎必須是innodb,由於galera目前只支持innodb的表。

mysql> show status like 'wsrep%';
........
  wsrep_local_state          | 4                                                      |
| wsrep_local_state_comment  | Synced                                                 |
| wsrep_cert_index_size      | 2                                                      |
| wsrep_causal_reads         | 0                                                      |
| wsrep_incoming_addresses   | 10.44.183.73:3306,10.51.58.169:3306,10.171.60.171:3306 |     
| wsrep_cluster_conf_id      | 9                                                      |
| wsrep_cluster_size         | 3                                                      |     //集羣成員是3個
| wsrep_cluster_state_uuid   | 92e43358-456d-11e7-af61-733b6b73c72c                   |
| wsrep_cluster_status       | Primary                                                |
| wsrep_connected            | ON                                                     |
| wsrep_local_bf_aborts      | 0                                                      |
| wsrep_local_index          | 2                                                      |
| wsrep_provider_name        | Galera                                                 |
| wsrep_provider_vendor      | Codership Oy <info@codership.com>                      |
| wsrep_provider_version     | 2.12(r318911d)                                         |
| wsrep_ready                | ON                                                     |
| wsrep_thread_count         | 2                

在node3上建立一個庫
mysql> create database wangshibo;
Query OK, 1 row affected (0.02 sec)

而後在node1和node2上查看,自動同步過來
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| wangshibo          |
+--------------------+
5 rows in set (0.00 sec)

在node1上的wangshibo庫下建立表,插入數據
mysql> use wangshibo;
Database changed
mysql> create table test(
    -> id int(5));
Query OK, 0 rows affected (0.11 sec)

mysql> insert into test values(1);
Query OK, 1 row affected (0.01 sec)

mysql> insert into test values(2);
Query OK, 1 row affected (0.02 sec)

一樣,在其它的節點上查看,也是能自動同步過來
mysql> select * from wangshibo.test;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)
相關文章
相關標籤/搜索