Mysql 主從複製,讀寫分離

 

一個簡單完整的 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選項。)

 

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");

	}
}

 

JDBC 連接更詳細的情況可以查看這篇 討論: http://www.iteye.com/topic/205926

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章