如何使用與維護,才能把MySQL GR發揮到極致?
作者介紹
賀春暘,普惠金融MySQL專家,《MySQL管理之道》第一版、第二版作者。曾任職於中國移動飛信、機鋒安卓市場,擁有豐富的數據庫管理經驗。目前致力於MySQL、Linux等開源技術的研究。
MySQL異步複製及semi-sync半同步複製,它們都基於MySQL binlog,原生複製是完全異步的,master不需要保證slave接收並執行了binlog,能夠保證master最大性能,但是slave可能存在延遲,主備數據無法保證一致性,在不停服務的前提下如果master宕機,提升slave為新的主庫,就會丟失數據。
semi-sync在異步複製基礎上增加了數據保護的考慮,這樣一來master必須確認slave收到binlog後(但不保證slave執行了事務)才能最終提交事務,若再結合MHA(Master High Availability)高可用架構,此時master掛掉之後,slave可以在apply完所有relay log後切換成master提供讀寫服務。
semi-sync半同步複製工作原理,如下圖所示。
相對於MySQL源生複製和semi-sync半同步複製,Group Replication全同步複製的差異是:
-
全同步複製,主備無延遲,一個節點宕機後其他兩個節點可以立即提供服務,而semi-sync需要應用(執行)完所有relay log,並依賴第三方高可用軟件實現數據不丟失;
-
事務衝突檢測保證數據一致性,多個節點可以同時讀寫數據,可以極大簡化數據訪問;
-
行級別並行複製,MySQL 5.7/MariaDB 10.0之前slave sql線程隻有一個,這個長期飽受詬病,是導致slave落後master的主要原因。
1 Group Replication的工作原理
使用的是基於認證的複製,其流程如下圖所示:
當客戶端發起commit命令時(此時仍然沒有發生真正的commit),所有本事務內對數據庫的更改行的主鍵都會被搜集到一個寫入集(writeset)中,該寫入集隨後會被複製到其他節點,該寫入集會在每個節點上使用搜索到的主鍵進行確認性認證測試來判斷該寫入集是否可以被應用。如果認證測試失敗,寫入集會被丟棄並且原始事務會被回滾;如果認證成功,事務會被提交並且寫入集會被在剩餘節點進行應用。最終,這意味著所有服務器以相同的順序接收同一組事務。
其他節點隻要驗證成功了,就會返回成功的信號,即使當前數據並沒有真正的寫入當前節點,固這裏的全同步複製,其實是虛擬的全同步複製。這段時間內,數據是有延遲的,但很小,如果應用程序訪問的是遠端節點,讀到的數據是未改變之前的舊數據。固在生產環境裏,對數據延遲要求很苛刻的情況下,建議在一個主節點上讀寫,避免造成數據不一致的情況發生。
(注:Galera通過設置參數wsrep_causal_reads = ON可以避免,這種情況下需要等待遠端節點應用完事務後,才返回客戶端讀取請求,這將增加讀取的響應時間。Group Replication未發現相關參數,如有朋友知道也請告知。)
而真正意義上的全同步複製,是要等所有節點事務都提交落地,才成功返回客戶端。因此虛擬全同步複製的性能會更好一些。
Group Replication內部實現了flow control限流措施,作用就是協調各個節點,保證所有節點執行事務的速度大於隊列增長速度,從而避免丟失事務。實現原理和簡單:整個Group Replication集群中,同時隻有一個節點可以廣播消息(數據),每個節點都會獲得廣播消息的機會(獲得機會後也可以不廣播),當慢節點的待執行隊列超過一定長度後,它會廣播一個FC_PAUSE消息,所以節點收到消息後都會暫緩廣播消息並不提供寫操作,直到該慢節點的待執行隊列長度減小到一定長度後,Group Replication數據同步又開始恢複。
變量參數:
group_replication_flow_control_applier_threshold = 25000
group_replication_flow_control_certifier_threshold = 25000
待執行隊列長度超過該值時,flow control被觸發,默認是25000。
-
全同步複製,事務要麼在所有節點都提交,要麼都回滾;
-
多主複製,可以在任意節點進行寫操作;
-
在從服務器上並行應用事件,真正意義上的並行複製;
-
節點自動配置--故障節點自動從集群中移除,當故障節點再次加入集群,無需手工備份當前數據庫並拷貝至故障節點;
-
應用程序的兼容性:無需更改應用程序,原生的MySQL接口;
-
生產環境上集群推薦配置3個節點;
-
每個節點都包含完整的數據副本;
-
各個節點的同步複製,通過GTID binlog ROW實現。
優點:
-
真正的多主架構,任何節點都可以進行讀寫,無需進行讀寫分離;
(注:生產環境建議隻在一台機器上寫,由於集群是樂觀鎖並發控製,事務衝突的情況會在commit階段發生。如果有兩個事務在集群中不同的節點上對同一行寫入並提交,失敗的節點將回滾,客戶端返回報錯,作為DBA你不想被一群開發投訴的話,還是默默的開啟Single-Primary寫入模式)
-
無集中管理,可以在任何時間點失去任何一個節點,集群將正常工作不受影響;
-
節點宕機不會導致數據丟失;
-
對應用透明。
缺點:
-
加入新節點,開銷大,需要複製完整的數據。
-
不能有效的解決寫擴展問題,磁盤空間滿了,無法自動擴容,不能像MongoDB分片那樣自動移動chunk做balance
-
有多少個節點就有多少份重複的數據
-
由於事務提交需要跨節點通訊(分布式事務),寫入會比主從複製慢
-
對網絡要求非常高,如果網絡出現波動或機房被ARP攻擊,造成兩個節點失聯,Group Replication集群發生腦裂,服務將不可用。
下麵是官方集群節點投票示意圖,如果是3個節點,必須滿足大多數節點2個投票,這裏很像MongoDB副本集的算法吧^_^
集群自身不提供VIP機製,也沒有像MongoDB副本集那樣提供JAVA/PHP客戶端API接口實現故障切換(需要開發自己寫,成本較高),需要結合第三方HaProxy軟件(建議2塊網卡做bond0)+自定義腳本實現秒級故障切換,另通過代理方式,性能會降低,因為多了一層網絡轉發。
局限性:
-
目前的複製僅僅支持InnoDB存儲引擎;
-
每張表必須有主鍵;
-
隻支持ipv4網絡;
-
集群最大支持9個節點;
-
不支持Savepoints;
-
不支持SERIALIZABLE隔離級別在Multi-Primary多主模式;
-
不支持外鍵在Multi-Primary多主模式;
-
整個集群的寫入吞吐量是由最弱的節點限製,如果有一個節點變得緩慢,比如硬盤故障(RAID10壞了一塊盤),那麼整個集群將是緩慢的。為了穩定的高性能要求,所有的節點應使用統一的硬件。
3 Group Replication的使用
Single-Primary模式配置環境:
1、設置host解析
三台服務器的配置如下:
# cat /etc/hosts
192.168.17.133 node1 192.168.17.134 node2 192.168.17.135 node3 |
2、編輯/etc/my.cnf配置參數(三個節點按照如下設置)
log-bin = /data/mysql57/binlog/mysql-bin binlog_format = ROW sync_binlog = 1 binlog_checksum = NONE log_slave_updates = 1 gtid_mode = ON enforce_gtid_consistency = ON master_info_repository = TABLE relay_log_info_repository = TABLE |
3、安裝插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so'; |
4、設置集群參數(三個節點都執行)
set global transaction_write_set_extraction = "XXHASH64"; set global group_replication_start_on_boot = ON; set global group_replication_bootstrap_group = OFF; set global group_replication_group_name = "13dd01d4-d69e-11e6-9c80-000c2937cddb"; set global group_replication_local_address = '192.168.17.133:6606'; set global group_replication_group_seeds = '192.168.17.133:6606,192.168.17.134:6606,192.168.17.135:6606'; set global group_replication_single_primary_mode = ON; |
注:group_replication_group_name名字要通過select uuid()來生成
group_replication_local_address在節點2和節點3上改成本地IP地址
執行完了,別忘了修改my.cnf裏加入到配置文件裏。
5、節點加入集群
Primary節點上執行
SET SQL_LOG_BIN=0; GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl'; FLUSH PRIVILEGES; SET SQL_LOG_BIN=1; CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery'; SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; select * from performance_schema.replication_group_members; SET GLOBAL group_replication_bootstrap_group=OFF; |
注:待replication_group_members表查詢結果MEMBER_STATE字段狀態為ONLINE,再執行關閉初始化。
兩台Secondary上執行
SET SQL_LOG_BIN=0; GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl'; FLUSH PRIVILEGES; SET SQL_LOG_BIN=1; CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery'; START GROUP_REPLICATION; select * from performance_schema.replication_group_members; |
如下圖所示,代表集群已經成功運行。
4 Group Replication的維護
假如Secondary節點宕機,重啟後由於種種原因加入集群失敗,現需要重新恢複,步驟如下:
1、在另一台Secondary節點上mysqldump全量
mysqldump -uroot -p123456 -q --single-transaction --master-data=2 -B yourDB > /root/yourDB.sql |
這一步會自動在yourDB.sql裏生成
SET @@GLOBAL.GTID_PURGED='23e510dc-d30b-11e6-a4c6-b82a72d18b06:1,4d1fd6ec-d2fd-11e6-ae4b-549f3503ab31:1-1543112:2003786-2003789:3003787,e4e34dd3-d2fa-11e6-984b-b82a72d18b06:1';
2、導入進去
再執行下麵的語句即可
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery'; START GROUP_REPLICATION; |
5 Group Replication總結
由於5.7.17版本剛剛GA,所以直接上生產環境風險太高,至少1年後小版本超過5.7.40以後再考慮。
原文發布時間為:2017-01-12
本文來自雲棲社區合作夥伴DBAplus
最後更新:2017-05-15 17:01:52