| 方案 | 類型 | 優點 | 缺點 |
| MySQL ReplicationDriver | 驅動層 | 無中間件、零運維、原生支持、輕量 | 客戶端感知拓撲、故障切換能力弱 |
| MyCat / ShardingSphere | 中間件 | 透明化、強大分片、完善監控 | 部署複雜、性能損耗、單點風險 |
| ProxySQL | 代理層 | 高性能、連接池、查詢重寫、熔斷 | 需單獨部署、配置較複雜 |
適用場景:中小型應用、微服務架構、希望減少基礎設施組件 時,驅動層方案極具性價比。
核心原理
JDBC URL 格式:
jdbc:mysql:replication://master_host,slave1_host,slave2_host/dbname?参数
- 第一個 Host 必須是 Master
- 後續 Host 為 Slave 列表
- 驅動自動識別
Connection.setReadOnly(true/false) 路由讀寫
Java 代碼實戰
import com.mysql.jdbc.ReplicationDriver;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Properties;
public class ReplicationDemo {
public static void main(String[] args) throws Exception {
ReplicationDriver driver = new ReplicationDriver();
Properties props = new Properties();
// 連接池相關優化
props.put("autoReconnect", "true");
props.put("failOverReadOnly", "false");
props.put("roundRobinLoadBalance", "true"); // Slave 輪詢負載均衡
props.put("maxReconnects", "3");
props.put("initialTimeout", "2");
// 認證信息
props.put("user", "app_user");
props.put("password", "AppPass123!");
// 建立連接 (Master: 192.168.1.10, Slaves: .11, .12)
String url = "jdbc:mysql:replication://192.168.1.10,192.168.1.11,192.168.1.12/app_db";
Connection conn = driver.connect(url, props);
try {
// 1. 寫操作路由到 Master
conn.setReadOnly(false);
conn.setAutoCommit(false);
conn.createStatement().executeUpdate(
"INSERT INTO orders (user_id, amount) VALUES (1001, 99.90)"
);
conn.commit();
System.out.println("寫入成功 -> Master");
// 2. 讀操作路由到 Slave (輪詢)
conn.setReadOnly(true);
ResultSet rs = conn.createStatement().executeQuery(
"SELECT * FROM orders WHERE user_id = 1001 ORDER BY created_at DESC LIMIT 5"
);
while (rs.next()) {
System.out.println("讀取: " + rs.getString("order_no") + " -> Slave");
}
// 3. 事務中強制走 Master
conn.setReadOnly(false);
conn.setAutoCommit(false);
// ... 業務邏輯
conn.commit();
} finally {
conn.close();
}
}
}
關鍵配置參數詳解
| 參數 | 默認值 | 建議值 | 說明 |
| autoReconnect | false | true | 連接斷開自動重連 |
| roundRobinLoadBalance | false | true | Slave 輪詢負載均衡 |
| failOverReadOnly | true | false | 故障切換後是否只讀 |
| maxReconnects | 3 | 3-5 | 最大重連次數 |
| loadBalanceBlacklistTimeout | 0 | 5000 | 黑名單超時(ms),暫時剔除故障節點 |
| readFromMasterWhenNoSlaves | false | true | 無可用 Slave 時回退 Master |
局限性與應對
- 無自動故障切換:Master 掛掉需應用層感知重連新 Master,建議配合 Orchestrator/MHA 實現自動切換並更新 JDBC URL
- 事務一致性:寫入後立即讀取可能讀到舊數據 (複製延遲),關鍵業務寫後讀強制
setReadOnly(false) 走 Master
- 連接池整合:HikariCP/Druid 需自定義 ConnectionProvider 支持 ReplicationDriver
總結
MySQL Connector/J ReplicationDriver 提供了零中間件、原生驅動級的讀寫分離能力。通過 setReadOnly() 簡單控制路由,配合輪詢負載均衡,適合中小型應用快速落地。生產環境建議:監控複製延遲、關鍵讀強制走 Master、配合外部故障切換工具。
- 上一篇文章: Docker 部署 MySQL 主從復制完整實戰指南
- 下一篇文章: Linux 下基於 OpenSSL 實現 MySQL 主從 SSL 加密復制
Copyright ©
程式碼之家 All Rights Reserved