MySQL Connector/J failover協(xié)議
MySQL Connector/J支持 failover 協(xié)議:即Client鏈接失效時(shí)扁誓,將會嘗試與其他host建立連接,這個過程對應(yīng)用是透明的瑞躺。Failover協(xié)議是“Multi-Host”模式中最基礎(chǔ)的協(xié)議,“l(fā)oad balancing”尼变、“replication”完丽、“farbic”協(xié)議都基于Failover協(xié)議励七。其URL格式如下:
jdbc:mysql://[primary-host]:[port],[secondary-host]:[port],.../[database]?[property=<value>]&[property=<value>]
Host列表中有兩種hosts:primary(master)和secondaries(slaves),priamry需要位于hosts列表的第一個;當(dāng)創(chuàng)建一個新的連接時(shí)变抽,會首先嘗試與primary連接础拨,如果primary連接異常氮块,將會依次與secondaries建立連接直到成功為止。即使與primary的鏈接失效诡宗,但是并不會丟失primary的特殊狀態(tài):比如它的訪問模式滔蝉、優(yōu)先級等。
連接屬性
Failover協(xié)議支持以下屬性:
- failOverReadOnly
- secondsBeforeRetryMaster
- queriesBeforeRetryMaster
- retriesAllDown
- autoReconnect
- autoReconnectForPools
failOverReadOnly用于控制連接中“read_only”參數(shù)僚焦,即當(dāng)primary連接失效時(shí)锰提,連接到secondary時(shí)的默認(rèn)訪問模式,此值默認(rèn)為“true”芳悲,即與secondary的連接訪問模式為“只讀”立肘。
primary的連接訪問模式總是“read/write”,即read_only為false名扛。當(dāng)與primary的連接失敗谅年,如果failOverReadOnly為false,表示與secondary的連接上允許發(fā)生“write”操作肮韧,與secondary的連接訪問模式也是“read/write”融蹂。
在failover發(fā)生后,會定期檢測primary的鏈接狀況弄企,如果發(fā)現(xiàn)primary的連接恢復(fù)正常超燃,那么連接會“Fallback”(回落)到primary上,即此后的read/write將在primary連接上發(fā)生(與secondary的連接將會保持空閑拘领,或者斷開)意乓。“secondsBeforeRetryMaster”表示驅(qū)動每隔多少秒將重試master的連接约素,“queriesBeforeRetryMaster”表示執(zhí)行多少次queries后重試master的連接届良,如果重試成功,則將連接“Fallback”到primary上圣猎∈亢可以將上述兩個屬性設(shè)置為“0”來關(guān)閉自動Fallback。
當(dāng)primary的連接失效后送悔,觸發(fā)failover慢显,此時(shí)驅(qū)動將依次與hosts列表中的secondary建立連接,直到與某個Secondary連接成功欠啤,否則將所有的secondaries都嘗試完畢鳍怨,然后繼續(xù)從頭開始,直到與其中一個secondary連接成功跪妥。如果所有的hosts都無法連接鞋喇,驅(qū)動最多重試“retriesAllDown”次(默認(rèn)為120)。
測試
-
MySQL部署結(jié)構(gòu)
2.JDBC設(shè)置:
db.url = jdbc:mysql://172.16.21.193:3306,172.16.21.191:3306/testdb?failOverReadOnly=false&secondsBeforeRetryMaster=0&queriesBeforeRetryMaster=0&retriesAllDown=120&autoReconnect=false
每秒訪問MySQL進(jìn)行一次查詢眉撵,在日志中打印時(shí)間侦香。
-
當(dāng)觸發(fā)一次MySQL主從切換落塑,舊主解綁 172.16.21.193,新主綁定 172.16.21.191罐韩,看日志每隔3s才會訪問一次 172.16.21.191憾赁,這顯然是有問題的:
-
抓包分析得知,每次訪問 172.16.21.191 后散吵,會發(fā)3次 ARP 廣播詢問 172.16.21.193 的 mac 地址龙考,每隔1s 發(fā)一次,剛好 3s:
- 對比測試枚冗,將 VIP 換成真實(shí) IP:
db.url = jdbc:mysql://172.16.21.5:3306,172.16.21.4:3306
關(guān)閉 172.16.21.5:3306 這個 MySQL缓溅,觀察到每次連接 MySQL 時(shí),都先嘗試連接 172.16.21.5:3306 赁温,再連接 172.16.21.4:3306坛怪。不同的是很快就會收到 RST 重連信號,不會阻塞與 172.16.21.4:3306 的連接股囊。此處不會有 arp袜匿,因?yàn)?arp -a 查看到的 arp 緩存一直都有真實(shí)IP的mac地址。
測試結(jié)論
從前面分析可以推得結(jié)論:
MySQL-JDBC 驅(qū)動每次訪問 host 列表都需要檢測 primary host 的連通性稚疹,如果 primary host IP 地址不在 arp 緩存中沉帮,則會發(fā)3次 arp 廣播,導(dǎo)致連接 secondary host 時(shí)有3s 延遲贫堰,這對應(yīng)用來說延遲太大。secondsBeforeRetryMaster=0&queriesBeforeRetryMaster=0 看起來失效了(本來作用是定義 primary host 連接檢測失敗后待牵,不再檢測 primary host)
但是:
嘗試修改 JDBC 其他參數(shù)(autoReconnect=true)其屏,發(fā)現(xiàn)并不是每次訪問 secondary host 即 172.16.21.191 前都需要 arp 廣播尋找 primary host 即 172.16.21.193,而是隔多少秒才會進(jìn)行 arp 廣播缨该。與前面的結(jié)論又相矛盾偎行。
因此本次探索MySQL Connector J 高級特性 failover 協(xié)議以一頭霧水告終,留此記錄希望以后能解開這個謎團(tuán)贰拿。
MySQL Connector/J loadbalance協(xié)議
Load Balancing可以將read/write負(fù)載蛤袒,分布在多個MySQL實(shí)例上,這些MySQL實(shí)例通常為 Cluster 架構(gòu)或者 Replication 架構(gòu)膨更,本文主要講解“Replication”架構(gòu)相關(guān)的知識妙真。LB協(xié)議基于“Failover協(xié)議”,即具備Failover特性荚守,其URL格式:jdbc:mysql:loadbalance://[host]:[port],[host]:[port],...[/database]?[property=<value>]&[property=<value>]