1. 程式人生 > >MySql-JDBC故障轉移

MySql-JDBC故障轉移

MySQL Connector/J 支援故障轉移,故障轉移在潛在的風險要發生的時候使用,通常情況下,資料庫連線發生錯誤,需要客戶端的異常處理(重新建立Statement、ResultSet、重啟程序),而使用Mysql Replication-Driver能夠實現自動故障轉移,當一個庫發生宕機,將連線連到其他存活的庫上,來實現主從高可用。

使用者只需像使用普通jdbc連線一樣,就可以在故障發生時,無感知的實現故障轉移,配置故障轉移的jdbc URL如下:

jdbc:mysql://[primary host][:port],[secondary host 1][:port][,[secondary host 2][:port]]...[/[database]]»
[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

在這個URL中包含兩種主機,主庫Master和從庫Slave。

  • 主庫宕機,從庫可讀
  • 從庫宕機,主庫可寫,另一臺從庫可讀
  • readFromMaster=true,情況下,主庫也可讀

故障轉移由以下連線屬性支援:

  • failOverReadOnly
  • secondsBeforeRetryMaster
  • queriesBeforeRetryMaster
  • retriesAllDown
  • autoReconnect
  • autoReconnectForPools

配置連線模式

在一些標準連線裡,主節點的初始化連線是可讀可寫的。然而,如果驅動確定到主節點的連線失敗,將會自動切換到列表中的下一個節點,連線模式依賴於failOverReadOnly這個屬性,預設是true,相似的,從節點的連線失敗,主節點也會變成可讀,可寫的,不管主節點之前是否被連線過,連線的模式都可以通過呼叫connection.setReadOnly()方法進行改變(實際重寫了failOverReadOnly),

  • 情況A:FailOverReadOnly=true
    a.到主節點的連線是可讀、可寫
    b.設定主節點readOnly屬性是true,主節點是隻讀模式
    c.FailOver事件發生;連線到從節點是隻讀模式
    d.設定readOnly=false,到第二個節點的連線是隻讀
    e.主節點恢復後,主節點是可讀、可寫的

  • 情況B:FailOverReadOnly=false
    a.連線到主節點是可讀、可寫的
    b.設定主節點readOnly屬性是true,主節點是隻讀模式
    c.FailOver事件發生;連線到從節點是隻讀模式
    d.設定readOnly=false,到第二個節點的連線是可讀、可寫
    e.主節點恢復後,主節點是可讀、可寫的

區別在於第四部,FailOver發生時,情況A第二個節點的讀寫模式不變,主節點不可用,直到主節點恢復前,整個叢集只讀;情況B立刻切換成第二個節點,可讀、可寫

配置恢復主節點

像之前提到過的,主節點在FailOver機制中是特別的,驅動預設希望儘快的恢復主節點,即便沒有連線異常發生,兩個屬性,secondsBeforeRetryMaster和queriesBeforeRetryMaster決定了什麼時候重試到主節點的連線

  • secondsBeforeRetryMaster 決定了嘗試連線到主節點前等多長時間
  • queriesBeforeRetryMaster 決定了驅動嘗試連線到主節點前,執行查詢的數量。每次執行Statement.execute*(),查詢計數器+1,因此,當Statement.executeBatch() 或 allowMultiQueries 或 rewriteBatchStatements 可用時,查詢計數器是不準確的,這意味著,queriesBeforeRetryMaster只是一個粗略計算的引數。

通常情況下,嘗試到主節點的連線檢查,只有在上述兩個條件滿足下才會進行,並且嘗試總是發生在事務的界限內,如果將autoCommit關閉了,這個檢查只會發生在Connection.commit() 或 Connection.rollback()呼叫時。如果同時設定secondsBeforeRetryMaster 和 queriesBeforeRetryMaster 為 “0”,自動恢復主節點將會被關閉,設定其中一個為0,只會禁用部分檢查。

配置重連

當確定一個新的連線,或者FailOver發生的時候,驅動嘗試連續的連線候選主機(Slaves幾點),最後一個節點嘗試完,再從第一個節點開始嘗試。當 a)並非所有的次節點至少嘗試一個重試連線 b)通過secondsBeforeRetryMaster 和queriesBeforeRetryMaster條件定義的連線重試不滿足條件時,主節點的重試連線將會被跳過。整個主機列表(不一定在主機列表的末尾完成)的連線重試,計為一次重試連線,一共嘗試retriesAllDown次(預設120)

無縫重連

儘管不建議,你可以使驅動在執行failover時,不作廢通過設定 autoReconnect 或 autoReconnectForPools 為 true所產生的Statement和ResultSet ,這要求客戶端在failover後繼續使用相同的例項,不採取任何異常措施,這將會造成意想不到的後果,例如:如果驅動通過讀/寫模式連線到主節點,並且他failover到一個只讀的從節點,這時候寫請求將會報錯,而且客戶端沒法感知,這種限制在使用資料流時特別相關,在failover後,resultSet看起來很正常,但潛在的連線可能已經改變了,並且再也沒有回退方案了。