Galera replication for MySQL

Galera replication for MySQL

By gpfeng | 2014 年 4 月 13 日

這篇文章總結了之前對Galera replication的調研,內容包括Galera特性,原理,Galera cluster配置,參數及性能等

Galera replication是什麼

MySQL DBA及開發應該都知道MySQL源生複製及semi-sync半同步複製,它們都基於MySQL binlog,原生複製是完全異步的,master不需要保證slave接收並執行了binlog,能夠保證master最大性能,但是slave可能存在延遲,主備數據無法保證一致性,在不停服務的前提下如果master宕機讓slave頂上,就會丟失數據,semi-sync在異步複製基礎上增加了數據保護的考慮,master必須確認slave收到binlog後(但不保證slave執行了事務)才能最終提交事務,在沒有退化(延遲較大時可能發生)成異步複製之前可以保證數據安全,此時master掛掉之後,slave可以在apply完所有relay log後切換成master提供讀寫服務

Galera replication是codership提供的MySQL數據同步方案,具有高可用,易於擴展等特點,它將多個MySQL節點組織成一個cluster

Galera replication特性

1. 同步複製,主備無延遲
2. 支持多主同時讀寫,保證數據一致性
3. 集羣中各節點保存全量數據
4. 節點添加/刪除,自動檢測和配置
5. 行級別並行複製
6. 不需要寫binlog

相對於MySQL源生複製和semi-sync,Galera replication比較有吸引力的特性:
1. 同步複製,主備無延遲,master宕機後slave可以立即頂上並提供服務(semi-sync需要apply完所有relay log)
2. 事務衝突檢測保證數據一致性,多個節點可以同時讀寫數據,可以極大簡化數據訪問
3. 行級別並行複製,MySQL 5.6之前slave sql線程只有一個,這個長期飽受詬病,是導致slave落後master的主要原因

Galera replicateion限制

1. 集羣至少3個節點(2個節點也可以運行)
2. 存儲引擎:Innodb / XtraDB / Maria
3. 不支持的SQL:LOCK / UNLOCK TABLES / GET_LOCK(), RELEASE_LOCK()…
4. 不支持XA Transaction

目前可用的產品:MariaDB Galera Cluster 和 Percona XtraDB Cluster

Galera replication原理

Galera replication是一種Certification based replication,保證one-copy serializability,理論基於這兩篇論文:Don’t be lazy, be consistent 和 Database State Machine Approach

算法示意圖

Galera_certification
圖片來自上面兩篇論文

算法僞代碼(Certification包含了後續流程,來自上面兩篇論文)

Galera_algorithm

事務執行協議

遵守deferred update replication,事務在commit時才複製到其他節點,執行過程分爲4個階段:

1.Local read phase
  a) 本地(client連接到的節點)執行事務Ti,但不真正提交,真正提交之前進入Send phase
2.Send phase
  a) 若事務只讀,直接提交,結束(多版本,只讀事務不加鎖)
  b) 將事務的寫操作封裝成WS(Write Set,基於行),廣播到所有節點(包括自身)
3.Lock / Certificaion phase
  a) 對收到的WS中的每個WSi(X)
    i. 若X沒有被加鎖,對X加鎖
    ii. 若X已被Tj加鎖且Tj處於Local read phase/Send phase,回滾Tj,對X加鎖
    iii. Certification based conflict detect
4.Write phase
  a) 若檢測出衝突,回滾Ti
  b) 否則,執行WS,提交事務後釋放鎖資源
  c) 對於源節點,提交事務並向client返回結果

客戶端/Galera節點信息交互圖

Galera_Certification_1
圖片來自mysqlperformanceblog

Galera replication採取的是樂觀策略,即事務在一個節點提交時,被認爲與其他節點上的事務沒有衝突,首先在本地“執行”(之所以帶引號,是因爲事務沒有執行完)後再發送到所有節點做衝突檢測,存在兩種情況下需要回滾事務:
1. WS複製到其它節點,被加到每個節點的slave trx queue中,與queue中前面的trxs在做certification test時發現衝突
2. WS通過了certification test後被保證一定會執行,在它執行過程中,如果該節點上有與其衝突的local trxs(Local phase),回滾local trxs

Galera提供了兩個狀態參數記錄衝突:
wsrep_local_cert_failures:certification test中未通過的trx數目
wsrep_local_bf_aborts:apply trxs(已經通過certification test)時,回滾的local trxs(open but not commit)數目

因此事務在commit節點廣播後,節點之間不交換“是否衝突”的信息,各個節點獨立異步的處理該事務,certification based replication協議保證:
1. 事務在所有節點上要麼都commit,要麼都rollback/abort
2. 事務在所有節點的執行順序一致

Certification based replication所依賴的基礎技術:
Group Communication System
1) Atomic delivery (事務傳輸要麼成功傳給了所有節點,要麼都失敗)
2) Total order (事務在所有節點中的順序一致)
3) Group maintenance (每個節點知道所有節點的狀態)

傳統的2PC(兩階段提交)做法

1. 2PC 事務結束時,所有節點數據達到一致
2. 協調者與參與者之間通信,參與者之間無連接
3. 受網絡狀態影響較大
4. 兩次通信,需要得到每個參與者的反饋後才能決定是否提交事務

因此Galera replicateion相對於2PC減少了網絡傳輸次數,消除了等待節點返回“決定是否衝突”的時間,從而可以提高了性能

Galera replication原理總結

1. 事務在本地節點執行時採取樂觀策略,成功廣播到所有節點後再做衝突檢測
2. 檢測出衝突時,本地事務優先被回滾
3. 每個節點獨立、異步執行隊列中的WS
4. 事務T在A節點執行成功返回客戶端後,其他節點保證T一定會被執行,因此有可能存在延遲,即虛擬同步
Galera_latency

Galera flow control

galera是同步複製(虛擬同步)方案,事務在本地節點(客戶端提交事務的節點)上提交成功時,其它節點保證執行該事務。在提交事務時,本地節點把事務複製到所有節點後,之後各個節點獨立異步地進行certification test、事務插入待執行隊列、執行事務。然而由於不同節點之間執行事務的速度不一樣,長時間運行後,慢節點的待執行隊列可能會越積越長,最終可能導致事務丟失。

galera內部實現了flow control,作用就是協調各個節點,保證所有節點執行事務的速度大於隊列增長速度,從而避免丟失事務。實現原理和簡單:整個galera cluster中,同時只有一個節點可以廣播消息(數據),每個節點都會獲得廣播消息的機會(獲得機會後也可以不廣播),當慢節點的待執行隊列超過一定長度後,它會廣播一個FC_PAUSE消息,所以節點收到消息後都會暫緩廣播消息,直到該慢節點的待執行隊列長度減小到一定長度後,galera cluster數據同步又開始恢復

flow control相關參數:

gcs.fc_limit:待執行隊列長度超過該值時,flow control被觸發,對於Master-Slave模式(只在一個節點寫)的galera cluster,可以配置一個較大的值,對啓動多寫的galera cluster,較小的值比較合適,因爲較大待執行隊列長度意味着更大的衝突,默認值16
gcs.fc_factor:當待執行隊列長度開始小於(gcs.fc_factor*gcs.fc_limit)時,數據同步恢復,默認0.5
gcs.fc_master_slave:galera cluster是否爲Master-Slave模式,默認

安裝MariaDB Galera Cluster

安裝準備:

1. MariaDB Galera Cluster 5.5.28a RC
1) https://downloads.mariadb.org/mariadb-galera/5.5.28a/
2) patched MariaDB 5.5.28,代碼中增加了Galera Library API(wsrep API),並在事務、鎖、handler等模塊添加/修改了調用邏輯

2. Galera wsrep provider
1) https://launchpad.net/galera/+download
2) Galera Library的實現,其中實現了group communication system, certification

編譯安裝

1. MariaDB Galera Cluster 5.5.28a RC
1) 與MariaDB基本相同,cmake時增加兩項:-DWITH_WSREP=ON , -DWITH_INNODB_DISALLOW_WRITES=1.
2. Galera wsrep provider: 源碼編譯後得到libgalera_smm.so(需要用到scons)

參數配置(每個節點)

wsrep_provider = /path/to/libgalera_smm.so
wsrep_cluster_address = cluster connection URL(後面詳細介紹)
binlog_format = ROW
default_storage_engine = INNODB
innodb_autoinc_lock_mode = 2
innodb_locks_unsafe_for_binlog = 1

選配:(可以提高性能,galera保證不丟數據)
innodb_flush_log_at_trx_commit = 2

構建集羣(三個節點)

3-node-cluster
節點名稱 IP地址
galera_node1 10.0.0.11
galera_node2 10.0.0.22
galera_node3 10.0.0.33

新建Galera Cluster

以galera_node1作爲第一個節點新建集羣,在my.cnf中配置參數:

wsrep_cluster_address = gcomm://
wsrep_cluster_name = galera_cluster
wsrep_node_address = 10.0.0.11
wsrep_node_name = galera_node1
wsrep_sst_method = rsync

添加galera_node2節點

在my.cnf中配置wsrep_cluster_address爲node1的ip或者hostname

wsrep_cluster_address = gcomm://10.0.0.11
wsrep_cluster_name = galera_cluster
wsrep_node_address = 10.0.0.22
wsrep_node_name = galera_node2
wsrep_sst_method = rsync

添加galera_node3節點

在my.cnf中配置wsrep_cluster_address爲node1的ip或者hostname

wsrep_cluster_address = gcomm://10.0.0.11
wsrep_cluster_name = galera_cluster
wsrep_node_address = 10.0.0.33
wsrep_node_name = galera_node3
wsrep_sst_method = rsync

多實例配置

因爲測試機器資源有限,需要在同一臺機器上啓動多個mysqld實例,爲每個mysqld配置兩個端口號(一個是mysql server端口號,默認3306;另外一個是wsrep端口號,默認4567),並修改部分wsrep配置參數,例如:

galera-cluster
節點名稱 IP地址 SERVER PORT WSREP PORT WSREP配置
galera_node1 127.0.0.1 3306 4405 wsrep_cluster_address=gcomm:// wsrep_node_address=127.0.0.1:4405 port=3306
galera_node2 127.0.0.1 3307 4407 wsrep_cluster_address=gcomm://127.0.0.1:4405 wsrep_node_address=127.0.0.1:4407 port=3307
galera_node3 127.0.0.1 308 4409 wsrep_cluster_addres=gcomm:// 127.0.0.1:4405 wsrep_node_address=127.0.0.1:4409 port=3308

啓動後在每個節點執行:

mysql> show status like ‘wsrep%;

當看到下述狀態時:

wsrep_connected=ON
wsrep_ready=ON
wsrep_cluster_status =Primary
wsrep_cluster_size=3(節點個數)

則galera集羣建立成功,如下圖所示:

Galera_status

說明:
1. MariaDB Galera Cluster 5.5.28a RC源碼安裝,在編譯時若沒有打開-DWITH_WSREP=ON, -DWITH_INNODB_DISALLOW_WRITES=1,或者沒有配置任何wsrep相關參數,它運行時就是一個普通的mysqld實例
2. Galera cluster複製不依賴於binlog文件,因此mysql-binlog和log-slave-updates都可以不配置,當然如果需要記錄binlog,也可以打開
3. 需要以wsrep_cluster_address = gcomm://啓動第一個節點後,才能相繼添加其他節點

Galera相關參數配置

InnoDB 相關參數

galera補丁版的mysql在cmake時需要指定:
-DWITH_WSREP=ON , -DWITH_INNODB_DISALLOW_WRITES=1

galera 目前只支持Innodb/xtradb/mariad存儲引擎
default_storage_engine = INNODB

爲了降低衝突,下列兩項需要設置
innodb_autoinc_lock_mode = 2
innodb_locks_unsafe_for_binlog = 1(gap不加鎖)

選配:(可以提高性能,galera保證不丟數據)
innodb_flush_log_at_trx_commit = 2

選配:galera可以不寫binlog,註釋binlog路徑理論上可以提高性能
#log-bin
#log-slave-updates=1

wsrep 相關參數

wsrep參數都是以wsrep_開頭的(30+個),其中有一個字符串參數(wsrep_provider_options)可以配置50+個更底層的參數。
可以通過“show variables like wsrep%”查看,wsrep_開頭參數,點擊查看詳情

列舉幾個重要的參數:

wsrep_auto_increment_control:控制auto_increment_increment=#nodes和auto_increment_offset=#node_id,默認ON
wsrep_causal_reads:默認是在本地節點讀,讀到的可能不是最新數據,開啓後將讀到最新數據,但會增加響應時間,默認OFF
wsrep_certify_nonPK:爲沒有顯示申明主鍵的表生成一個用於certification test的主鍵,默認ON
wsrep_cluster_address: 啓動節點時需要指定galera cluster的地址,作爲cluster中第一個啓動的節點,wsrep_cluster_address=gcomm://,對於後續啓動的節點,wsrep_cluster_address=gcomm://node1,node2,node3	
wsrep_cluster_name: 所有node必須一樣, 默認my_test_cluster
wsrep_convert_LOCK_to_trx:將LOCK/UNLOCK TABLES轉換成BEGIN/COMMIT,默認OFF
wsrep_data_home_dir:galera會生成一些文件,默認使用mysql_data_dir,默認mysql_data_dir
wsrep_node_name:節點名稱
wsrep_on:session/global,設置爲OFF時,事務將不會複製到其他節點,默認ON
wsrep_OSU_method:Online Schema Update設置,TOI/RSU(MySQL >= 5.5.17),默認TOI
wsrep_provider:libgalera_smm.so的路徑,若沒有配置,galera複製不會啓動,默認none
wsrep_provider_options:很長的字符串變量,可以配置很多group communication system相關參數,很長很長...
wsrep_retry_autocommit:事務在衝突時重新嘗試的次數,默認1
wsrep_slave_threads:並行複製的slave線程數,默認4
wsrep_sst_method:Snapshot State Transter方法:mysqldump/rsync/xt,默認mysqldump

wsrep_provider_options
該參數是一個字符串,包含了group communication system中很多參數設置,配置時使用分號隔開:
wsrep_provider_options=”key_a=value_a;key_b=value_b;key_c=value_c”,點擊查看詳情

列舉其中部分重要參數:

evs.send_window:節點一次可以發送的消息數目,默認4
evs.user_send_window:其與evs.send_window之間的差別類似於max_connections與max_user_connection,默認2
gcs.fc_factor:flow control參數,默認0.5
gcs.fc_limit:flow control參數,默認16
gcs.fc_master_slave:flow control參數,默認NO
gcs.recv_q_hard_limit:接收隊列的佔用的最大內存,默認LLONG_MAX
gcs.recv_q_soft_limit:當接收隊列佔用內存超過(gcs.recv_q_hard_limit*gcs.recv_q_soft_limit),複製被延遲,默認0.25
gmcast.listen_addr:節點用於接收其它節點消息的地址,默認tcp://0.0.0.0:4567
pc.checksum:是否對發送的消息做checksum,默認true
pc.ignore_sb:是否忽略split brain,默認false

一個例子

binlog_format=row 
default-storage-engine = INNODB 
innodb_autoinc_lock_mode = 2 
innodb_locks_unsafe_for_binlog = 1
wsrep_provider = /u01/mariadb-galera/lib/libgalera_smm.so 
wsrep_cluster_address = "gcomm://192.168.xxx.01" 
wsrep_cluster_name = galera 
wsrep_node_address = 192.168.xxx.xxx 
wsrep_node_name = slave 
wsrep_sst_method = rsync 
wsrep_slave_threads = 16 
wsrep_provider_options="gcache.page_size=128M;gcache.size=2G;gcs.fc_limit=512;gcs.fc_factor=0.9;evs.send_window=256;evs.user_send_window=128"

Galera status variables

Galera提供了很多以wsrep_開頭狀態參數監控mysql狀態,通過show status like ‘wsrep%’可以查看:

wsrep_local_state_uuid:應該與wsrep_cluster_state_uuid一致,如363acc29-9160-11e2-0800-4316271a76e4
wsrep_last_committed:已經提交事務數目,所有節點之間相差不大,可以用來計算延遲
wsrep_replicated:從本地節點複製出去的write set數目
wsrep_replicated_bytes:從本地節點複製出去的write set的總共字節數
wsrep_received:本地節點接收來自其他節點的write set數目
wsrep_received_bytes:本地節點接收來自其他節點的write set的總共字節數
wsrep_local_commits:從本地節點發出的write set被提交的數目,不超過wsrep_replicated
wsrep_local_cert_failures:certification test失敗的數目
wsrep_local_bf_aborts:certification test通過的write set執行過程中回滾的與其衝突的本地事務
wsrep_local_replays:事務被回滾(bf abort)重做的數目
wsrep_local_send_queue:發送隊列的長度
wsrep_local_send_queue_avg:從上次查詢狀態到目前發送隊列的平均長度,>0.0意味着複製過程被節流了
wsrep_local_recv_queue:接收隊列的長度
wsrep_local_recv_queue_avg:從上次查詢狀態到目前接收隊列的平均長度,>0.0意味着執行速度小於接收速度
wsrep_flow_control_paused:從上次查詢狀態到目前處於flow control的時間佔比,如0.388129
wsrep_flow_control_sent:從上次查詢狀態到目前節點發送出的FC_PAUSE消息數目,如1
wsrep_flow_control_recv:從上次查詢狀態到目前及節點接收的FC_PAUSE消息數目,如1
wsrep_cert_deps_distance:可以並行執行的write set的最大seqno與最小seqno之間的平均差值,如1851.825751
wsrep_apply_oooe:隊列中事務併發執行佔比,值越高意味着效率越高
wsrep_commit_window:平均併發提交窗口大小
wsrep_local_state:節點的狀態,取值1-6
wsrep_local_state_comment:節點的狀態描述,比如Synced
wsrep_incoming_addresses:集羣中其它節點的地址,多個地址之間用逗號分隔
wsrep_cluster_conf_id:集羣節點關係改變的次數(每次增加/刪除都會+1)
wsrep_cluster_size:集羣節點個數
wsrep_cluster_state_uuid:集羣uuid,所有節點應該一樣,如:363acc29-9160-11e2-0800-4316271a76e4
wsrep_cluster_status:集羣的目前狀態,取值:PRIMARY(正常)/NON_PRIMARY(不一致)
wsrep_connected:節點是否連接到集羣,取值:ON/OFF
wsrep_local_index:節點id
wsrep_provider_name:默認Galera
wsrep_provider_vendor:默認Codership Oy <[email protected]>
wsrep_provider_version:wsrep版本,如:2.2(rXXXX)
wsrep_ready:節點是否可以接受查詢了,取值:ON/OFF

一個截圖:

Galera_status_1

如何檢查節點是否加入到集羣

1. wsrep_cluster_state_uuid應該與其它所有節點相同
2. wsrep_cluster_conf_id應該與其它所有節點相同
3. wsrep_cluster_size應該是所有節點的數目
4. wsrep_cluster_status取值應該是:Primary
5. wsrep_ready取值應該是ON
6. wsrep_connected取值應該是ON

判斷複製過程是否出現問題

wsrep_flow_control_paused,正常情況下,其取值應該接近於0.0,大於0.0意味着有‘慢節點’影響了集羣的速度,可以嘗試通過增大wsrep_slave_threads來解決

找出最慢的節點

wsrep_flow_control_sent,wsrep_local_recv_queue_avg兩個值最大的節點

參考:galera statusgalera monitoring

性能測試

由於galera同步複製在每個寫事務提交時都增加了replicate trx和certification test的開銷,因此性能遠遠低於異步MySQL實例

測試場景

使用TPCC進行測試,包含3組數據:
1、normal mysql: baseline,單個mysql server
2、galera (RTT: 0.5ms): 2-nodes galera cluster,單節點讀寫
3、galera (RTT: 15.2ms): 2-nodes galera cluster,單節點讀寫

tpmC結果:
Galera_performance
TPS結果:
Galera_performance_tps

測試結論:

1. 相對於異步MySQL實例,Galera replication性能下降約50% ~ 60%左右
2. Galera最大性能不受RTT影響,RTT 較小時(0.5ms),在達到最大性能之前(32併發),性能下降並不明顯 (32併發下降25%,16併發性能下降更低),RTT較大時(15.2ms),在達到最大性能之前(64併發),相對於norml mysq性能下降一直到很明顯,當壓力逐漸增大,由於group io的原因,galera性能在達到最大時還會提高

Galera replication for MySQL學習資料

1. codership官網
2. mysqlperformanceblog搜索中PXC(Percona XtraDB Cluster)

Category: MySQL-InnoDB
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章