標籤:
一個簡單完整的 Mysql 主從複製,讀寫分離的。
1. 首先搭建 Mysql 主從架構,實現 將 mater 資料自動複製到 slave
MySQL 複製的工作方式很簡單,一台伺服器作為主機,一台或多台伺服器作為從機。主機會把資料庫的變化記錄到日誌。一旦這些變化被記錄到日誌,就會立刻(或者以設定的時間間隔)被送到從機。
使用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選項。)
Cnf代碼
- log-bin=mysql-bin #slave會基於此log-bin來做replication
- server-id=1 #master的標示
-
- innodb_flush_log_at_trx_commit=1
-
- sync_binlog=1
修改 slave.cnf
Cnf代碼
- [mysqld]
-
- server-id=2 #slave的標示
3. 啟動服務
Cnf代碼
- # 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 &
Java代碼
- # 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 簡單的讀寫分離實現
讀寫分離可以直接在 用戶端 實現, 也可以通過 Proxy 伺服器 實現。
Proxy 伺服器一般可以選擇:
官方的: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 直接實現 讀寫分離。
Java代碼
- 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");
-
- }
- }
mysql的主從複製原理