一個簡單完整的 Mysql 主從複製,讀寫分離的示意圖。java
1. 首先搭建 Mysql 主從架構,實現 將 mater 數據自動複製到 slavemysql
MySQL 複製的工做方式很簡單,一臺服務器做爲主機,一臺或多臺服務器做爲從機。主機會把數據庫的變化記錄到日誌。一旦這些變化被記錄到日誌,就會馬上(或者以設定的時間間隔)被送到從機。sql
使用MySQL 複製提供擴展大型網站的能力,這些大型網站的數據庫主要是讀操做(SELECTs)。從機用於複製主機的銷秏是不多的(一般每一個從機1%的開銷),在大型網站中每一個主機部署30 個從機也是常見的。數據庫
異步複製與同步複製服務器
異步複製:MySQL自己支持單向的、異步的複製。異步複製意味着在把數據從一臺機器拷貝到另外一臺機器時有一個延時 – 最重要的是這意味着當應用系統的事務提交已經確認時數據並不能在同一時刻拷貝/應用到從機。一般這個延時是由網絡帶寬、資源可用性和系統負載決定的。然而,使用正確的組件而且調優,複製能作到接近瞬時完成。網絡
同步複製:同步複製能夠定義爲數據在同一時刻被提交到一臺或多臺機器,一般這是經過衆所周知的「兩階段提交」作到的。雖然這確實給你在多系統中保持一致性,但也因爲增長了額外的消息交換而形成性能降低。架構
使用MyISAM或者InnoDB存儲引擎的MySQL自己並不支持同步複製,然而有些技術,例如分佈式複製塊設備(簡稱DRBD),能夠在下層的文件系統提供同步複製,容許第二個MySQL服務器在主服務器丟失的狀況下接管(使用第二服務器的複本)。要了解更多信息,請參見:http://www.drbd.org/異步
異步複製方案:分佈式
1. Mysql 數據庫安裝性能
安裝過程省略: 詳細參見:http://pengranxiang.iteye.com/admin/blogs/1138059
服務器 Master :192.168.14.131
Mysql 安裝目錄: /home/mysql/mysql (使用源碼安裝,獨立目錄)
服務器 Slave :192.168.14.132
Mysql 安裝目錄 :/home/mysql/mysql
2. 修改配置
爲了避免影響原來的配置文件: /etc/my.cnf
建立新的配置文件,
cp /etc/my.cnf /home/mysql/mysql/conf/master.cnf
cp /etc/my.cnf /home/mysql/mysql/conf/slave.cnf
修改 master.cnf, 增長下面的設置 ,
(官方說明:爲了使用事務的InnoDB在複製中最大的持久性和一致性,你應該指定innodb_flush_log_at_trx_commit=1,sync_binlog=1選項。)
log-bin=mysql-bin #slave會基於此log-bin來作replication
server-id=1 #master的標示
innodb_flush_log_at_trx_commit=1
sync_binlog=1
修改 slave.cnf
[mysqld]
server-id=2 #slave的標示
3. 啓動服務
# Master
# 若是 Mysql 已啓動,先關掉。
/home/mysql/mysql/bin/mysqladmin -u root -p shutdown
# 使用修改過的 master.cnf 啓動 mysql
/home/mysql/mysql/bin/mysqld_safe --defaults-file=/home/mysql/mysql/conf/master.cnf &
# Slave
# 若是 Mysql 已啓動,先關掉。
/home/mysql/mysql/bin/mysqladmin -u root -p shutdown
# 使用修改過的 slave.cnf 啓動 mysql
/home/mysql/mysql/bin/mysqld_safe --defaults-file=/home/mysql/mysql/conf/slave.cnf &
4. 在 Master 上建立一個專門用於複製的帳號 repl_user
5. 啓動主從複製功能
須要查看 Master 中的 Master status
mysql> show master status;
而後再 Slave 中,啓動複製
上面窗口是鏈接 Master , 下面窗口鏈接 Slave
6. 測試複製
在 Master 中插入一條數據, 而後在 Slave 中查詢。 能夠驗證。
2 簡單的讀寫分離實現
讀寫分離能夠直接在 客戶端 實現, 也能夠經過 代理服務器 實現。
代理服務器通常能夠選擇:
官方的:mysql proxy 地址:http://dev.mysql.com/downloads/mysql-proxy/#downloads
國產開源項目:amoeba
Amoeba開發者博客: http://amoeba.meidusa.com
Amoeba開源項目地址: http://www.sourceforge.net/projects/amoeba
amoeba 中文文檔下載地址:http://amoeba.meidusa.com/amoeba.pdf
這裏只演示最簡單的方案: JDBC 直接實現 讀寫分離。
package prx.dao;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Properties;
import com.mysql.jdbc.ReplicationDriver;
public class Test {
public static void main(String[] args) throws Exception {
ReplicationDriver driver = new ReplicationDriver();
Properties props = new Properties();
// We want this for failover on the slaves
props.put("autoReconnect", "true");
// We want to load balance between the slaves
props.put("roundRobinLoadBalance", "true");
props.put("user", "foo");
props.put("password", "bar");
//
// Looks like a normal MySQL JDBC url, with a
// comma-separated list of hosts, the first
// being the 'master', the rest being any number
// of slaves that the driver will load balance against
//
Connection conn = driver.connect(
"jdbc:mysql://master,slave1,slave2,slave3/test", props);
//
// Perform read/write work on the master
// by setting the read-only flag to "false"
//
// 經過 conn 的 readOnly 是否爲 true 來判斷,要取 connection 鏈接的數據庫是 主數據庫,仍是從數據庫
// false 爲 主數據庫的鏈接
// true 爲 從數據庫的鏈接
conn.setReadOnly(false);
conn.setAutoCommit(false);
conn.createStatement().executeUpdate("UPDATE some_table ....");
conn.commit();
//
// Now, do a query from a slave, the driver automatically picks one
// from the list
//
conn.setReadOnly(true);
ResultSet rs = conn.createStatement().executeQuery(
"SELECT a,b FROM alt_table");
}
}