MySQL Group Replication 介绍
2016-12-12,一個(gè)重要的日子,mysql5.7.17 GA版發(fā)布,正式推出Group Replication(組復(fù)制) 插件,通過這個(gè)插件增強(qiáng)了MySQL原有的高可用方案(原有的Replication方案),提供了重要的特性——多寫,保證組內(nèi)高可用,確保數(shù)據(jù)最終一致性。
1. 背景
在介紹組復(fù)制之前,我們先簡單介紹傳統(tǒng)的異步復(fù)制和半同步復(fù)制:
1.1 傳統(tǒng)復(fù)制
傳統(tǒng)mysql復(fù)制是完全異步化的復(fù)制。下圖描述了傳統(tǒng)復(fù)制的原理:
master事務(wù)的提交不需要經(jīng)過slave的確認(rèn),slave是否接收到master的binlog,master并不care。slave接收到master binlog后先寫relay log,最后異步地去執(zhí)行relay log中的sql應(yīng)用到自身。由于master的提交不需要確保slave relay log是否被正確接受,當(dāng)slave接受master binlog失敗或者relay log應(yīng)用失敗,master無法感知。
假設(shè)master發(fā)生宕機(jī)并且binlog還沒來得及被slave接收,而切換程序?qū)lave提升為新的master,就會(huì)出現(xiàn)數(shù)據(jù)不一致的情況!另外,在高并發(fā)的情況下,傳統(tǒng)的主從復(fù)制,從節(jié)點(diǎn)可能會(huì)與主產(chǎn)生較大的延遲(當(dāng)然mysql后續(xù)版本陸續(xù)做了優(yōu)化,推出了并行復(fù)制,以此降低異步復(fù)制的延遲)。
1.2 半同步復(fù)制
基于傳統(tǒng)異步存在的缺陷,mysql在5.5版本推出半同步復(fù)制。可以說半同步復(fù)制是傳統(tǒng)異步復(fù)制的改進(jìn),在master事務(wù)的commit之前,必須確保一個(gè)slave收到relay log并且響應(yīng)給master以后,才能進(jìn)行事務(wù)的commit。但是slave對于relay log的應(yīng)用仍然是異步進(jìn)行的,原理如下圖所示:
因?yàn)閟lave接受relay log之后有可能apply失敗。這個(gè)時(shí)候master其實(shí)不知道slave的失敗,照常提交了這個(gè)事務(wù)。并且,半同步復(fù)制只確保一個(gè)slave能夠收到relay log,多slave的場景下,不能保證其他節(jié)點(diǎn)正確收到relay log,由此,當(dāng)發(fā)生master切換后,半同步復(fù)制一樣也會(huì)出現(xiàn)數(shù)據(jù)不一致的情況。
1.3 組復(fù)制
基于傳統(tǒng)異步復(fù)制和半同步復(fù)制的缺陷——數(shù)據(jù)的一致性問題無法保證,MySQL官方在5.7.17版本正式推出組復(fù)制(MySQL Group Replication,簡稱MGR)。
由若干個(gè)節(jié)點(diǎn)共同組成一個(gè)復(fù)制組,一個(gè)事務(wù)的提交,必須經(jīng)過組內(nèi)大多數(shù)節(jié)點(diǎn)(N / 2 + 1)決議并通過,才能得以提交。如上圖所示,由3個(gè)節(jié)點(diǎn)組成一個(gè)復(fù)制組,Consensus層為一致性協(xié)議層,在事務(wù)提交過程中,發(fā)生組間通訊,由2個(gè)節(jié)點(diǎn)決議(certify)通過這個(gè)事務(wù),事務(wù)才能夠最終得以提交并響應(yīng)。
引入組復(fù)制,主要是為了解決傳統(tǒng)異步復(fù)制和半同步復(fù)制可能產(chǎn)生數(shù)據(jù)不一致的問題。組復(fù)制依靠分布式一致性協(xié)議(Paxos協(xié)議的變體),實(shí)現(xiàn)了分布式下數(shù)據(jù)的最終一致性,提供了真正的數(shù)據(jù)高可用方案(是否真正高可用還有待商榷)。其提供的多寫方案,給我們實(shí)現(xiàn)多活方案帶來了希望。
一個(gè)復(fù)制組由若干個(gè)節(jié)點(diǎn)(數(shù)據(jù)庫實(shí)例)組成,組內(nèi)各個(gè)節(jié)點(diǎn)維護(hù)各自的數(shù)據(jù)副本(Share Nothing),通過一致性協(xié)議實(shí)現(xiàn)原子消息和全局有序消息,來實(shí)現(xiàn)組內(nèi)實(shí)例數(shù)據(jù)的一致。
2. 組復(fù)制介紹
一句話簡介:基于分布式一致性協(xié)議Paxos實(shí)現(xiàn)數(shù)據(jù)最終一致性的MySQL插件。上面的介紹也已經(jīng)大概地描述了組復(fù)制的相關(guān)概念以及它的誕生背景,下面我們關(guān)注于它的一些特性:
2.1 數(shù)據(jù)一致性保證
對于只讀(RO)事務(wù),組間實(shí)例無需進(jìn)行通訊,就可以處理事務(wù);但是對于讀寫(RW)事務(wù),需要經(jīng)過組內(nèi)大多數(shù)節(jié)點(diǎn)決議,來決定該事務(wù)是否可以提交。
引用mysql官方博客對于讀寫事務(wù)提交過程的描述,解釋了如何保證了組內(nèi)節(jié)點(diǎn)間數(shù)據(jù)的一致性的:
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 事務(wù)并發(fā)沖突處理
在高并發(fā)的多寫模式(MGR的一種運(yùn)行模式)下,節(jié)點(diǎn)間事務(wù)的提交可能會(huì)產(chǎn)生沖突,比如,兩個(gè)不同的事務(wù)在兩個(gè)節(jié)點(diǎn)上操作了同一行數(shù)據(jù),這個(gè)時(shí)候就會(huì)產(chǎn)生沖突。首先,Group Replication(GR)能夠識(shí)別到這個(gè)沖突,然后對此的處理采用樂觀策略:依賴事務(wù)提交的時(shí)間先后順序,先發(fā)起提交的節(jié)點(diǎn)能夠正確提交,而后面的提交,會(huì)失敗。
2.3 節(jié)點(diǎn)故障自動(dòng)檢測
GR自帶故障檢測機(jī)制,可以識(shí)別組內(nèi)成員是否掛掉(組內(nèi)節(jié)點(diǎn)心跳檢測)。當(dāng)一個(gè)節(jié)點(diǎn)失效,將由其他節(jié)點(diǎn)決定是否將這個(gè)失效的節(jié)點(diǎn)從group里面剔除。當(dāng)然,這是建立在滿足大多數(shù)節(jié)點(diǎn)存活并且可以進(jìn)行決議的前提上的。
2.4 組成員自動(dòng)管理
GR自動(dòng)維護(hù)組內(nèi)節(jié)點(diǎn)的狀態(tài)(在線?存活?掛掉?),對于失效的節(jié)點(diǎn),由其他節(jié)點(diǎn)決定是否剔除。對于新加入的節(jié)點(diǎn),GR會(huì)自動(dòng)維護(hù)它的視圖與其他節(jié)點(diǎn)的視圖保持一致。關(guān)于集群內(nèi)節(jié)點(diǎn)的狀態(tài),可以通過performance_schema.replication_group_members表查看:
舉個(gè)例子:
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個(gè)節(jié)點(diǎn)組成一個(gè)GR組,然后狀態(tài)都是ONLINE(最正常的狀態(tài))。可以在組內(nèi)的3個(gè)節(jié)點(diǎn)上都看到這個(gè)統(tǒng)一的視圖。
有些同學(xué)可能會(huì)問,上面視圖中的MEMBER_HOST是怎么顯示成IP的,其實(shí)這個(gè)是通過my.cnf配置文件里面指定report_host而來的,若沒有配置report_host,則MEMBER_PORT將顯示為主機(jī)名
2.5 容錯(cuò)能力
GR基于分布式一致性算法實(shí)現(xiàn),一個(gè)組允許部分節(jié)點(diǎn)掛掉,只要保證大多數(shù)節(jié)點(diǎn)仍然存活并且之間的通訊是沒有問題的,那么這個(gè)組對外仍然能夠提供服務(wù)。
假設(shè)一個(gè)GR由2n + 1個(gè)節(jié)點(diǎn),那么允許n個(gè)節(jié)點(diǎn)失效,這個(gè)GR仍然能夠?qū)ν馓峁┓?wù)。比如有3個(gè)節(jié)點(diǎn)組成的一個(gè)GR,可允許1個(gè)節(jié)點(diǎn)失效,這個(gè)GR仍然能夠提供服務(wù)。
| 1 | 1 | 0 |
| 2 | 2 | 0 |
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
| 6 | 4 | 2 |
| 7 | 4 | 3 |
【注意】若不滿足大多數(shù),所有事務(wù)寫操作都會(huì)阻塞,直到集群滿足大多數(shù)節(jié)點(diǎn)存活為止。
GR一般由奇數(shù)個(gè)節(jié)點(diǎn)組成為佳,是從最節(jié)省機(jī)器的角度考慮,你用4臺(tái)機(jī)器,一樣只能掛1臺(tái)。
2.6 兩種模式
GR提供了single-primary和multi-primary兩種模式。single-primary模式下,組內(nèi)只有一個(gè)節(jié)點(diǎn)負(fù)責(zé)寫入,讀可以從任意一個(gè)節(jié)點(diǎn)讀取,組內(nèi)數(shù)據(jù)保持最終一致;而multi-primary模式即為多寫方案,即寫操作會(huì)下發(fā)到組內(nèi)所有節(jié)點(diǎn),組內(nèi)所有節(jié)點(diǎn)同時(shí)可讀可寫,該模式也是能夠保證組內(nèi)數(shù)據(jù)最終一致性。
注意,一個(gè)GR的所有節(jié)點(diǎn)必須配置使用同一種模式,不可混用。比如說A、B、C三個(gè)節(jié)點(diǎn)組成一個(gè)GR組,那么要么都運(yùn)行在single-primary模式下,要么都運(yùn)行在multi-primary模式下。
由my.cnf里的配置項(xiàng)group_replication_single_primary_mode來配置節(jié)點(diǎn)到底是運(yùn)行在single-primary模式還是multi-primary模式
2.6.1 Single-Primary Mode
這個(gè)模式下,group內(nèi)只有一臺(tái)節(jié)點(diǎn)可寫可讀,其他節(jié)點(diǎn)只可以讀。對于group的部署,需要先跑起primary節(jié)點(diǎn)(即那個(gè)可寫可讀的節(jié)點(diǎn),read_only = 0)然后再跑起其他的節(jié)點(diǎn),并把這些節(jié)點(diǎn)一一加進(jìn)group。其他的節(jié)點(diǎn)就會(huì)自動(dòng)同步primary節(jié)點(diǎn)上面的變化,然后將自己設(shè)置為只讀模式(read_only = 1)。
當(dāng)primary節(jié)點(diǎn)意外宕機(jī)或者下線,在滿足大多數(shù)節(jié)點(diǎn)存活的情況下,group內(nèi)部發(fā)起選舉,選出下一個(gè)可用的讀節(jié)點(diǎn),提升為primary節(jié)點(diǎn)。
primary選舉根據(jù)group內(nèi)剩下存活節(jié)點(diǎn)的server_uuid按字典序升序來選擇,即剩余存活的節(jié)點(diǎn)按server_uuid字典序排列,然后選擇排在最前的節(jié)點(diǎn)作為新的primary節(jié)點(diǎn)。
引用?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不會(huì)處理應(yīng)用重連接到新的主,這需要應(yīng)用層自己或者由另外的中間件層(proxy or router)去保證。
如何查看group內(nèi)哪個(gè)節(jié)點(diǎn)是作為primary節(jié)點(diǎn),官方提供了一個(gè)方法:
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
得到的是實(shí)例節(jié)點(diǎn)的server_uuid。利用上面的SQL,加上performance_schema里的replication_group_members表,可以查出更細(xì)節(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來直接判斷當(dāng)前節(jié)點(diǎn)是否為主節(jié)點(diǎn),得到1表示主節(jié)點(diǎn),0表示不是主節(jié)點(diǎn):
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ā)現(xiàn)一個(gè)便捷的方式,可以通過直接查看read_only變量來判斷節(jié)點(diǎn)是否為主節(jié)點(diǎn):
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的概念(無需進(jìn)行選舉),group內(nèi)的所有機(jī)器都是primary節(jié)點(diǎn),同時(shí)可以進(jìn)行讀寫操作,并且數(shù)據(jù)是最終一致的。但是,這個(gè)模式下仍然存在一些使用限制,限制請看2.7.2小節(jié)介紹。
2.7 約束與限制
2.7.1 約束
部署GR有以下需求:
1)?架構(gòu)上
- 存儲(chǔ)引擎必須為innodb
- 每個(gè)表必須提供主鍵
- 只支持ipv4,網(wǎng)絡(luò)帶寬要好
- 一個(gè)group最多只能有9個(gè)節(jié)點(diǎn)
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é)已經(jīng)提及
- 不支持Savepoints
- multi-primary mode部署方式不支持SERIALIZABLE事務(wù)隔離級(jí)別
- multi-primary mode部署方式不能完全支持級(jí)聯(lián)外鍵約束
- multi-primary mode部署方式不支持在不同節(jié)點(diǎn)上對同一個(gè)數(shù)據(jù)庫對象并發(fā)執(zhí)行DDL(在不同節(jié)點(diǎn)上對同一行并發(fā)進(jìn)行RW事務(wù),后發(fā)起的事務(wù)會(huì)失敗)
轉(zhuǎn)載于:https://www.cnblogs.com/qiumingcheng/p/7199496.html
總結(jié)
以上是生活随笔為你收集整理的MySQL Group Replication 介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java 虚拟机探索之路系列】:JIT
- 下一篇: JDBC(11)—数据库连接池