文件首頁
MySQL Connector/J 開發人員指南
相關文件 下載本手冊
PDF (US Ltr) - 1.2Mb
PDF (A4) - 1.2Mb


MySQL Connector/J 開發人員指南  /  多主機連線  /  使用 Connector/J 設定來源/複本複寫

9.4 使用 Connector/J 設定來源/複本複寫

本節描述 Connector/J 支援複寫感知部署的數個功能。

複寫是在伺服器連線的初始設定階段透過連線 URL 來設定,其格式與MySQL 連線的通用 JDBC URL類似,但具有專用的配置。

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

使用者可以指定屬性allowSourceDownConnections=true,即使沒有來源主機可連線,也允許建立 Connection 物件。此類 Connection 物件會回報它們是唯讀的,且 isSourceConnection() 會對它們傳回 false。當呼叫 Connection.setReadOnly(false) 時,Connection 會測試可用的來源主機,如果無法建立與來源的連線,則會擲回 SQLException,如果主機可用,則會切換到來源連線。

使用者可以指定屬性allowReplicasDownConnections=true,即使沒有複本主機可連線,也允許建立 Connection 物件。然後,Connection 在執行階段,當呼叫 Connection.setReadOnly(true) 時(請參閱下方的方法說明),會測試可用的複本主機,如果無法建立與複本的連線,則會擲回 SQLException,除非屬性 readFromSourceWhenNoReplicas 設定為 true(請參閱下方屬性的說明)。

透過將讀取流量分散到複本來擴展讀取負載

Connector/J 支援複寫感知連線。它可以根據 Connection.getReadOnly() 的狀態,自動將查詢傳送到讀寫來源主機,或一組容錯移轉或循環配置負載平衡的複本。

應用程式會呼叫 Connection.setReadOnly(true) 來表示它想要交易為唯讀。複寫感知連線將使用其中一個複本連線,這些連線會使用循環配置方案,針對每個複本主機進行負載平衡。指定的連線會與複本保持黏性,直到發出交易界限命令(commit 或 rollback),或直到從服務中移除複本。在呼叫 Connection.setReadOnly(true) 之後,如果您想要在沒有複本可用時允許連線到來源,請將屬性 readFromSourceWhenNoReplicas 設定為 true。 請注意,在這些情況下,來源主機將以唯讀狀態使用,如同它是複本主機。另請注意,設定 readFromSourceWhenNoReplicas=true 可能會以透明的方式導致來源主機額外的負載。

如果您有寫入交易,或者如果您有時間敏感的讀取(請記住,MySQL 中的複寫是非同步的),請呼叫 Connection.setReadOnly(false) 將連線設定為非唯讀,驅動程式將確保進一步的呼叫會傳送到來源 MySQL 伺服器。驅動程式會負責在它用來完成此負載平衡功能的所有連線之間傳播 autocommit、隔離等級和目錄的目前狀態。

若要啟用此功能,請在連線到伺服器時使用專用的複寫配置 ( jdbc:mysql:replication://)。

以下是在獨立應用程式中如何使用複寫感知連線的簡短範例

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Properties;
import java.sql.DriverManager;

public class ReplicationDemo {

  public static void main(String[] args) throws Exception {
  
    Properties props = new Properties();

    // We want this for failover on the replicas
    props.put("autoReconnect", "true");

    // We want to load balance between the replicas
    props.put("roundRobinLoadBalance", "true");

    props.put("user", "foo");
    props.put("password", "password");

    //
    // Looks like a normal MySQL JDBC url, with a
    // comma-separated list of hosts, the first
    // being the 'source', the rest being any number
    // of replicas that the driver will load balance against
    //

    Connection conn =
        DriverManager.getConnection("jdbc:mysql:replication://source,replica1,replica2,replica3/test",
            props);

    //
    // Perform read/write work on the source
    // by setting the read-only flag to "false"
    //

    conn.setReadOnly(false);
    conn.setAutoCommit(false);
    conn.createStatement().executeUpdate("UPDATE some_table ....");
    conn.commit();

    //
    // Now, do a query from a replica, the driver automatically picks one
    // from the list
    //

    conn.setReadOnly(true);

    ResultSet rs =
      conn.createStatement().executeQuery("SELECT a,b FROM alt_table");

     .......
  }
}

考慮使用負載平衡 JDBC 集區 (lbpool) 工具,它提供標準 JDBC 驅動程式的包裝函式,並允許您使用包含系統故障和負載分配不均檢查的資料庫連線集區。如需詳細資訊,請參閱MySQL 的負載平衡 JDBC 驅動程式 (mysql-lbpool)

支援多來源複寫拓撲

Connector/J 支援多來源複寫拓撲。

先前討論的複寫連線 URL(即,格式為 jdbc:mysql:replication://source,replica1,replica2,replica3/test)假設第一個(且只有第一個)主機是來源主機。支援具有任意數量的來源和複本的部署,需要第 6.2 節「連線 URL 語法」中討論的多主機連線的「位址等於」URL 語法,以及屬性 type=[source|replica];例如

jdbc:mysql:replication://address=(type=source)(host=source1host),address=(type=source)(host=source2host),address=(type=replica)(host=replica1host)/database

Connector/J 在內部使用負載平衡連線來管理來源連線,這表示 ReplicationConnection 在設定為使用多個來源時,會公開與第 9.3 節「使用 Connector/J 設定負載平衡」中描述的相同的選項,以便在來源主機之間平衡負載。

複寫拓撲的即時重新設定

Connector/J 也支援複寫主機(單一或多來源)拓撲的即時管理。這讓使用者可以在不需要重新啟動應用程式的情況下,為 Java 應用程式升級複本。

複寫主機最好在複寫連線群組的環境中進行管理。 `ReplicationConnectionGroup` 類別代表一個可一起管理的連線邏輯群組。在給定的 Java 類別載入器中,可能有一個或多個此類複寫連線群組(一個應用程式可能具有兩個需要獨立管理的 JDBC 資源)。這個關鍵類別公開了複寫連線的主機管理方法,並且如果指定了新的 `replicationConnectionGroup` 屬性的值,`ReplicationConnection` 物件會向適當的 `ReplicationConnectionGroup` 註冊自己。`ReplicationConnectionGroup` 物件會追蹤這些連線直到它們關閉,並且它用於操作與這些連線相關聯的主機。

一些與主機管理相關的重要方法包括:

  • getSourceHosts():傳回一個字串集合,代表設定為來源主機的主機。

  • getReplicaHosts():傳回一個字串集合,代表設定為複寫主機的主機。

  • addReplicaHost(String host):將新的主機新增至可能的複寫主機池,以便在新的唯讀工作負載開始時選擇。

  • promoteReplicaToSource(String host):從未來唯讀程序的潛在複寫主機池中移除主機(允許現有的唯讀程序繼續完成),並將該主機新增至潛在的來源主機池。

  • removeReplicaHost(String host, boolean closeGently):從已設定的複寫主機清單中移除主機(主機名稱必須完全相符);如果 closeGently 為 false,則會強制關閉目前將此主機作為作用中的現有連線(應用程式應預期會出現例外狀況)。

  • removeSourceHost(String host, boolean closeGently):與 removeReplicaHost() 相同,但會從已設定的來源主機清單中移除主機。

一些有用的管理指標包括:

  • getConnectionCountWithHostAsReplica(String host):傳回將給定主機設定為可能的複寫主機的 `ReplicationConnection` 物件數量。

  • getConnectionCountWithHostAsSource(String host):傳回將給定主機設定為可能的來源主機的 `ReplicationConnection` 物件數量。

  • getNumberOfReplicasAdded():傳回將複寫主機動態新增至群組池的次數。

  • getNumberOfReplicasRemoved():傳回將複寫主機從群組池中動態移除的次數。

  • getNumberOfReplicaPromotions():傳回將複寫主機升級為來源主機的次數。

  • getTotalConnectionCount():傳回已向此群組註冊的 `ReplicationConnection` 物件數量。

  • getActiveConnectionCount():傳回目前由這個群組管理的 `ReplicationConnection` 物件數量。

ReplicationConnectionGroupManager

com.mysql.cj.jdbc.ha.ReplicationConnectionGroupManager 提供對複寫連線群組的存取,以及一些公用程式方法。

  • getConnectionGroup(String groupName):傳回與提供的 groupName 相符的 `ReplicationConnectionGroup` 物件。

`ReplicationConnectionGroupManager` 中的其他方法與 `ReplicationConnectionGroup` 的方法相同,只是第一個引數是字串群組名稱。這些方法將對所有相符的 ReplicationConnectionGroups 執行操作,這對於從服務中移除伺服器並使其在所有可能的 `ReplicationConnectionGroups` 中停用很有幫助。

如果應用程式觸發拓撲變更,這些方法可能對於 JVM 內部管理複寫主機很有用。若要從 JVM 外部管理主機組態,可以使用 JMX。

使用 JMX 管理複寫主機

當 Connector/J 以 ha.enableJMX=true 啟動並為屬性 replicationConnectionGroup 設定值時,將會註冊一個 JMX MBean,允許 JMX 用戶端操作複寫主機。MBean 介面定義在 com.mysql.cj.jdbc.jmx.ReplicationGroupManagerMBean 中,並利用 `ReplicationConnectionGroupManager` 的靜態方法。

 public abstract void addReplicaHost(String groupFilter, String host) throws SQLException;
 public abstract void removeReplicaHost(String groupFilter, String host) throws SQLException;
 public abstract void promoteReplicaToSource(String groupFilter, String host) throws SQLException;
 public abstract void removeSourceHost(String groupFilter, String host) throws SQLException;
 public abstract String getSourceHostsList(String group);
 public abstract String getReplicaHostsList(String group);
 public abstract String getRegisteredConnectionGroups();
 public abstract int getActiveSourceHostCount(String group);
 public abstract int getActiveReplicaHostCount(String group);
 public abstract int getReplicaPromotionCount(String group);
 public abstract long getTotalLogicalConnectionCount(String group);
 public abstract long getActiveLogicalConnectionCount(String group);

使用 DNS SRV 設定來源/複寫複寫

有關詳細資訊,請參閱第 6.14 節,「支援 DNS SRV 記錄」