MySQL Group Replication 介绍
2016-12-12,一個重要的日子,mysql5.7.17 GA版發(fā)布,正式推出Group Replication(組復制) 插件,通過這個插件增強了MySQL原有的高可用方案(原有的Replication方案),提供了重要的特性——多寫,保證組內高可用,確保數據最終一致性。
1. 背景
在介紹組復制之前,我們先簡單介紹傳統的異步復制和半同步復制:
1.1 傳統復制
傳統mysql復制是完全異步化的復制。下圖描述了傳統復制的原理:
master事務的提交不需要經過slave的確認,slave是否接收到master的binlog,master并不care。slave接收到master binlog后先寫relay log,最后異步地去執(zhí)行relay log中的sql應用到自身。由于master的提交不需要確保slave relay log是否被正確接受,當slave接受master binlog失敗或者relay log應用失敗,master無法感知。
假設master發(fā)生宕機并且binlog還沒來得及被slave接收,而切換程序將slave提升為新的master,就會出現數據不一致的情況!另外,在高并發(fā)的情況下,傳統的主從復制,從節(jié)點可能會與主產生較大的延遲(當然mysql后續(xù)版本陸續(xù)做了優(yōu)化,推出了并行復制,以此降低異步復制的延遲)。
1.2 半同步復制
基于傳統異步存在的缺陷,mysql在5.5版本推出半同步復制。可以說半同步復制是傳統異步復制的改進,在master事務的commit之前,必須確保一個slave收到relay log并且響應給master以后,才能進行事務的commit。但是slave對于relay log的應用仍然是異步進行的,原理如下圖所示:
因為slave接受relay log之后有可能apply失敗。這個時候master其實不知道slave的失敗,照常提交了這個事務。并且,半同步復制只確保一個slave能夠收到relay log,多slave的場景下,不能保證其他節(jié)點正確收到relay log,由此,當發(fā)生master切換后,半同步復制一樣也會出現數據不一致的情況。
1.3 組復制
基于傳統異步復制和半同步復制的缺陷——數據的一致性問題無法保證,MySQL官方在5.7.17版本正式推出組復制(MySQL Group Replication,簡稱MGR)。
由若干個節(jié)點共同組成一個復制組,一個事務的提交,必須經過組內大多數節(jié)點(N / 2 + 1)決議并通過,才能得以提交。如上圖所示,由3個節(jié)點組成一個復制組,Consensus層為一致性協議層,在事務提交過程中,發(fā)生組間通訊,由2個節(jié)點決議(certify)通過這個事務,事務才能夠最終得以提交并響應。
引入組復制,主要是為了解決傳統異步復制和半同步復制可能產生數據不一致的問題。組復制依靠分布式一致性協議(Paxos協議的變體),實現了分布式下數據的最終一致性,提供了真正的數據高可用方案(是否真正高可用還有待商榷)。其提供的多寫方案,給我們實現多活方案帶來了希望。
一個復制組由若干個節(jié)點(數據庫實例)組成,組內各個節(jié)點維護各自的數據副本(Share Nothing),通過一致性協議實現原子消息和全局有序消息,來實現組內實例數據的一致。
2. 組復制介紹
一句話簡介:基于分布式一致性協議Paxos實現數據最終一致性的MySQL插件。上面的介紹也已經大概地描述了組復制的相關概念以及它的誕生背景,下面我們關注于它的一些特性:
2.1 數據一致性保證
對于只讀(RO)事務,組間實例無需進行通訊,就可以處理事務;但是對于讀寫(RW)事務,需要經過組內大多數節(jié)點決議,來決定該事務是否可以提交。
引用mysql官方博客對于讀寫事務提交過程的描述,解釋了如何保證了組內節(jié)點間數據的一致性的:
To be precise, when a transaction is ready to commit at the originating server, the server will atomically broadcasts the write values (rows changed) and the correspondent write set (unique identifiers of the rows that were updated). Then a global total order will be established for that transaction. Ultimately, this means that all servers receive the same set of transactions in the same order. As a consequence, all servers apply the same set of changes in the same order, therefore they remain consistent within the group.
2.2 事務并發(fā)沖突處理
在高并發(fā)的多寫模式(MGR的一種運行模式)下,節(jié)點間事務的提交可能會產生沖突,比如,兩個不同的事務在兩個節(jié)點上操作了同一行數據,這個時候就會產生沖突。首先,Group Replication(GR)能夠識別到這個沖突,然后對此的處理采用樂觀策略:依賴事務提交的時間先后順序,先發(fā)起提交的節(jié)點能夠正確提交,而后面的提交,會失敗。
2.3 節(jié)點故障自動檢測
GR自帶故障檢測機制,可以識別組內成員是否掛掉(組內節(jié)點心跳檢測)。當一個節(jié)點失效,將由其他節(jié)點決定是否將這個失效的節(jié)點從group里面剔除。當然,這是建立在滿足大多數節(jié)點存活并且可以進行決議的前提上的。
2.4 組成員自動管理
GR自動維護組內節(jié)點的狀態(tài)(在線?存活?掛掉?),對于失效的節(jié)點,由其他節(jié)點決定是否剔除。對于新加入的節(jié)點,GR會自動維護它的視圖與其他節(jié)點的視圖保持一致。關于集群內節(jié)點的狀態(tài),可以通過performance_schema.replication_group_members表查看:
舉個例子:
mysql> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ | group_replication_applier | 748703ac-dbcc-11e6-a668-90e2bac5d924 | 10.202.44.215 | 24801 | ONLINE | | group_replication_applier | 8f8bc352-2566-11e7-aa5e-d4ae52ab91b3 | 10.202.44.214 | 24801 | ONLINE | | group_replication_applier | 9c09340a-e04c-11e6-9916-0024e869a606 | 10.202.44.213 | 24801 | ONLINE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ 3 rows in set (0.00 sec)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
如上有3個節(jié)點組成一個GR組,然后狀態(tài)都是ONLINE(最正常的狀態(tài))。可以在組內的3個節(jié)點上都看到這個統一的視圖。
有些同學可能會問,上面視圖中的MEMBER_HOST是怎么顯示成IP的,其實這個是通過my.cnf配置文件里面指定report_host而來的,若沒有配置report_host,則MEMBER_PORT將顯示為主機名
2.5 容錯能力
GR基于分布式一致性算法實現,一個組允許部分節(jié)點掛掉,只要保證大多數節(jié)點仍然存活并且之間的通訊是沒有問題的,那么這個組對外仍然能夠提供服務。
假設一個GR由2n + 1個節(jié)點,那么允許n個節(jié)點失效,這個GR仍然能夠對外提供服務。比如有3個節(jié)點組成的一個GR,可允許1個節(jié)點失效,這個GR仍然能夠提供服務。
| 1 | 1 | 0 |
| 2 | 2 | 0 |
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
| 6 | 4 | 2 |
| 7 | 4 | 3 |
【注意】若不滿足大多數,所有事務寫操作都會阻塞,直到集群滿足大多數節(jié)點存活為止。
GR一般由奇數個節(jié)點組成為佳,是從最節(jié)省機器的角度考慮,你用4臺機器,一樣只能掛1臺。
2.6 兩種模式
GR提供了single-primary和multi-primary兩種模式。single-primary模式下,組內只有一個節(jié)點負責寫入,讀可以從任意一個節(jié)點讀取,組內數據保持最終一致;而multi-primary模式即為多寫方案,即寫操作會下發(fā)到組內所有節(jié)點,組內所有節(jié)點同時可讀可寫,該模式也是能夠保證組內數據最終一致性。
注意,一個GR的所有節(jié)點必須配置使用同一種模式,不可混用。比如說A、B、C三個節(jié)點組成一個GR組,那么要么都運行在single-primary模式下,要么都運行在multi-primary模式下。
由my.cnf里的配置項group_replication_single_primary_mode來配置節(jié)點到底是運行在single-primary模式還是multi-primary模式
2.6.1 Single-Primary Mode
這個模式下,group內只有一臺節(jié)點可寫可讀,其他節(jié)點只可以讀。對于group的部署,需要先跑起primary節(jié)點(即那個可寫可讀的節(jié)點,read_only = 0)然后再跑起其他的節(jié)點,并把這些節(jié)點一一加進group。其他的節(jié)點就會自動同步primary節(jié)點上面的變化,然后將自己設置為只讀模式(read_only = 1)。
當primary節(jié)點意外宕機或者下線,在滿足大多數節(jié)點存活的情況下,group內部發(fā)起選舉,選出下一個可用的讀節(jié)點,提升為primary節(jié)點。
primary選舉根據group內剩下存活節(jié)點的server_uuid按字典序升序來選擇,即剩余存活的節(jié)點按server_uuid字典序排列,然后選擇排在最前的節(jié)點作為新的primary節(jié)點。
引用?MySQL 5.7 Reference Manual?:
Upon primary member failure, an automatic leader election mechanism chooses the next primary member. The next primary is selected by ordering the remaining servers lexicographically (using their UUID) and picking the first member in the list.
【特別重要】?在切換primary期間,mysql group不會處理應用重連接到新的主,這需要應用層自己或者由另外的中間件層(proxy or router)去保證。
如何查看group內哪個節(jié)點是作為primary節(jié)點,官方提供了一個方法:
mysql> SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member'; +--------------------------------------+ | VARIABLE_VALUE | +--------------------------------------+ | 69e1a3b8-8397-11e6-8e67-bf68cbc061a4 | +--------------------------------------+ 1 row in set (0,00 sec)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
得到的是實例節(jié)點的server_uuid。利用上面的SQL,加上performance_schema里的replication_group_members表,可以查出更細節(jié)的信息,包括hostname,port等,sql語句如下所示:
SELECT * FROM performance_schema.replication_group_members WHERE MEMBER_ID = (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member' );- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
另外,還可以通過以下SQL來直接判斷當前節(jié)點是否為主節(jié)點,得到1表示主節(jié)點,0表示不是主節(jié)點:
mysql> SELECT IF((SELECT @@server_uuid) = (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member'), 1, 0) as is_primary_node; +-----------------+ | is_primary_node | +-----------------+ | 1 | +-----------------+ 1 row in set (0.00 sec)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
最后發(fā)現一個便捷的方式,可以通過直接查看read_only變量來判斷節(jié)點是否為主節(jié)點:
mysql> select @@read_only; +-------------+ | @@read_only | +-------------+ | 0 | +-------------+ 1 row in set (0.00 sec)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2.6.2 Multi-Primary Mode
多主模式,即多寫,沒有選擇新primary的概念(無需進行選舉),group內的所有機器都是primary節(jié)點,同時可以進行讀寫操作,并且數據是最終一致的。但是,這個模式下仍然存在一些使用限制,限制請看2.7.2小節(jié)介紹。
2.7 約束與限制
2.7.1 約束
部署GR有以下需求:
1)?架構上
- 存儲引擎必須為innodb
- 每個表必須提供主鍵
- 只支持ipv4,網絡帶寬要好
- 一個group最多只能有9個節(jié)點
2) 配置上
針對my.cnf,需要指定如下配置:
# Binary Log must be active. log-bin[=log_file_name]# Binary Log Format must be set to ROW. binlog-format=row # Global Transaction Identifiers must be turned on. gtid-mode=ON # Replication applier needs to have replication metadata repositories stored in system tables. master-info-repository=TABLE relay-log-info-repository=TABLE # Transaction write set extraction must be enabled. transaction-write-set-extraction=XXHASH64 # Servers need to log binary logs that are applied through the replication applier. log-slave-updates # Replication event checksums are not supported. binlog-checksum=NONE- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
2.7.2 限制
以下是使用GR的限制:
- 不支持Replication event checksums,需要在my.cnf里面配置,在上節(jié)已經提及
- 不支持Savepoints
- multi-primary mode部署方式不支持SERIALIZABLE事務隔離級別
- multi-primary mode部署方式不能完全支持級聯外鍵約束
- multi-primary mode部署方式不支持在不同節(jié)點上對同一個數據庫對象并發(fā)執(zhí)行DDL(在不同節(jié)點上對同一行并發(fā)進行RW事務,后發(fā)起的事務會失敗)
轉載于:https://www.cnblogs.com/qiumingcheng/p/7199496.html
總結
以上是生活随笔為你收集整理的MySQL Group Replication 介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java 虚拟机探索之路系列】:JIT
- 下一篇: mybatis02--增删改查