本節描述 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 記錄」。