1. 程式人生 > 其它 >Mycat+MySql 主從複製-讀寫分離

Mycat+MySql 主從複製-讀寫分離

​ 通過mycat和mysql的主從複製配合搭建資料庫的讀寫分離,可以實現mysql的高可用性,下面我們來搭建mysql的讀寫分離。

1、一主一從

1、在node01上修改/etc/my.cnf的檔案

#mysql服務唯一id,不同的mysql服務必須擁有全域性唯一的id
server-id=1
#啟動二進位制日期
log-bin=mysql-bin
#設定不要複製的資料庫
binlog-ignore-db=mysql
binlog-ignore-db=information-schema
#設定需要複製的資料庫
binlog-do-db=msb
#設定binlog的格式
binlog_format=statement

2、在node02上修改/etc/my.cnf檔案

#伺服器唯一id
server-id=2
#啟動中繼日誌
relay-log=mysql-relay

3、重新啟動mysql服務

4、在node01上建立賬戶並授權slave

grant replication slave on *.* to 'root'@'%' identified by '123456';
--在進行授權的時候,如果提示密碼的問題,把密碼驗證取消
set global validate_password_policy=0;
set global validate_password_length=1;

5、檢視master的狀態

show master status

6、在node02上配置需要複製的主機

CHANGE MASTER TO MASTER_HOST='192.168.85.111',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=437;

7、啟動從伺服器複製功能

start slave;

8、檢視從伺服器狀態

show slave status\G

​ 當執行完成之後,會看到兩個關鍵的屬性Slave_IO_Running,Slave_SQL_Running,當這兩個屬性都是yes的時候,表示主從複製已經準備好了,可以進行具體的操作了

2、一主一從驗證

​ 下面我們通過實際的操作來驗證主從複製是否完成。

--在node01上建立資料庫
create database msb;
--在node01上建立具體的表
create table mytbl(id int,name varchar(20));
--在node01上插入資料
insert into mytbl values(1,'zhangsan');
--在node02上驗證發現數據已經同步成功,表示主從複製完成

通過mycat實現讀寫分離

​ 在node01上插入如下sql語句,

-- 把主機名插入資料庫中
insert into mytbl values(2,@@hostname);
-- 然後通過mycat進行資料的訪問,這個時候大家發現無論怎麼查詢資料,最終返回的都是node01的資料,為什麼呢?
select * from mytbl;

​ 在之前的mycat基本配置中,其實我們已經配置了讀寫分離,大家還記得readHost和writeHost兩個標籤嗎?

<writeHost host="hostM1" url="192.168.85.111:3306" user="root"
				   password="123456">
			<readHost host="hostS1" url="192.168.85.112:3306" user="root" password="123456"></readHost>
		</writeHost>

​ 其實我們已經配置過了這兩個標籤,預設情況下node01是用來完成寫入操作的,node02是用來完成讀取操作的,但是剛剛通過我們的驗證發現所有的讀取都是node01完成的,這是什麼原因呢?

​ 原因很簡單,就是因為我們在進行配置的時候在 dataHost 標籤中缺失了一個非常重要的屬性balance,此屬性有四個值,用來做負載均衡的,下面我們來詳細介紹

​ 1、balance=0 :不開啟讀寫分離機制,所有讀操作都發送到當前可用的writehost上

​ 2、balance=1:全部的readhost和stand by writehost參與select 語句的負載均衡,簡單的說,當雙主雙從模式下,其他的節點都參與select語句的負載均衡

​ 3、balance=2:所有讀操作都隨機的在writehost,readhost上分發

​ 4、balance=3:所有讀請求隨機的分發到readhost執行,writehost不負擔讀壓力

​ 當了解了這個引數的含義之後,我們可以將此引數設定為2,就能夠看到在兩個主機上切換執行了。

3、雙主雙從

​ 在上述的一主一從的架構設計中,很容易出現單點的問題,所以我們要想讓生產環境中的配置足夠穩定,可以配置雙主雙從,解決單點的問題。

​ 在此架構中,可以讓一臺主機用來處理所有寫請求,此時,它的從機和備機,以及備機的從機複製所有讀請求,當主機宕機之後,另一臺主機負責寫請求,兩臺主機互為備機。

​ 主機分佈如下:

編號 角色 ip 主機名
1 master1 192.168.85.111 node01
2 slave1 192.168.85.112 node02
3 master2 192.168.85.113 node03
4 slave2 192.168.85.114 node04

​ 下面開始搭建雙主雙從。

​ 1、修改node01上的/etc/my.cnf檔案

#主伺服器唯一ID
server-id=1
#啟用二進位制日誌
log-bin=mysql-bin
# 設定不要複製的資料庫(可設定多個)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
#設定需要複製的資料庫
binlog-do-db=msb
#設定logbin格式
binlog_format=STATEMENT
# 在作為從資料庫的時候, 有寫入操作也要更新二進位制日誌檔案
log-slave-updates
#表示自增長欄位每次遞增的量,指自增欄位的起始值,其預設值是1, 取值範圍是1 .. 65535
auto-increment-increment=2
# 表示自增長欄位從哪個數開始,指欄位一次遞增多少,他的取值範圍是1 .. 65535
auto-increment-offset=1

​ 2、修改node03上的/etc/my.cnf檔案

#主伺服器唯一ID
server-id=3
#啟用二進位制日誌
log-bin=mysql-bin
# 設定不要複製的資料庫(可設定多個)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
#設定需要複製的資料庫
binlog-do-db=msb
#設定logbin格式
binlog_format=STATEMENT
# 在作為從資料庫的時候,有寫入操作也要更新二進位制日誌檔案
log-slave-updates
#表示自增長欄位每次遞增的量,指自增欄位的起始值,其預設值是1,取值範圍是1 .. 65535
auto-increment-increment=2
# 表示自增長欄位從哪個數開始,指欄位一次遞增多少,他的取值範圍是1 .. 65535
auto-increment-offset=2

​ 3、修改node02上的/etc/my.cnf檔案

#從伺服器唯一ID
server-id=2
#啟用中繼日誌
relay-log=mysql-relay

​ 4、修改node04上的/etc/my.cnf檔案

#從伺服器唯一ID
server-id=4
#啟用中繼日誌
relay-log=mysql-relay

​ 5、所有主機重新啟動mysql服務

​ 6、在兩臺主機node01,node03上授權同步命令

GRANT REPLICATION SLAVE ON *.* TO 'root'@'%' IDENTIFIED BY '123456';

​ 7、檢視兩臺主機的狀態

show master status;

​ 8、在node02上執行要複製的主機

CHANGE MASTER TO MASTER_HOST='192.168.85.111',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;

​ 9、在node04上執行要複製的主機

CHANGE MASTER TO MASTER_HOST='192.168.85.113',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;

​ 10、啟動兩個從機的slave並且檢視狀態,當看到兩個引數都是yes的時候表示成功

start slave;
show slave status;

​ 11、完成node01跟node03的相互複製

--在node01上執行
CHANGE MASTER TO MASTER_HOST='192.168.85.113',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=442;
--開啟slave
start slave
--檢視狀態
show slave status\G
--在node03上執行
CHANGE MASTER TO MASTER_HOST='192.168.85.111',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=442;
--開啟slave
start slave
--檢視狀態
show slave status\G

4、雙主雙從驗證

在node01上執行如下sql語句:

create database msb;
create table mytbl(id int,name varchar(20));
insert into mytbl values(1,'zhangsan');
--完成上述命令之後可以去其他機器驗證是否同步成功

​ 當上述操作完成之後,我們可以驗證mycat的讀寫分離,此時我們需要進行重新的配置,修改schema.xml檔案。

​ 在當前mysql架構中,我們使用的是雙主雙從的架構,因此可以將balance設定為1

​ 除此之外我們需要注意,還需要了解一些引數:

​ 引數writeType,表示寫操作傳送到哪臺機器,此引數有兩個值可以進行設定:

​ writeType=0:所有寫操作都發送到配置的第一個writeHost,第一個掛了切換到還生存的第二個

​ writeType=1:所有寫操作都隨機的傳送到配置的writehost中,1.5之後廢棄,

​ 需要注意的是:writehost重新啟動之後以切換後的為準,切換記錄在配置檔案dnindex.properties中

​ 引數switchType:表示如何進行切換:

​ switchType=1:預設值,自動切換

​ switchType=-1:表示不自動切換

​ switchType=2:基於mysql主從同步的狀態決定是否切換

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
	<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
	</schema>
	<dataNode name="dn1" dataHost="host1" database="msb" />
	<dataHost name="host1" maxCon="1000" minCon="10" balance="1"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<writeHost host="hostM1" url="192.168.85.111:3306" user="root"
				   password="123456">
			<readHost host="hostS1" url="192.168.85.112:3306" user="root" password="123456"></readHost>
		</writeHost>
		<writeHost host="hostM2" url="192.168.85.113:3306" user="root"
				   password="123456">
			<readHost host="hostS2" url="192.168.85.114:3306" user="root" password="123456"></readHost>
		</writeHost>
	</dataHost>
</mycat:schema>

​ 下面開始進行讀寫分離的驗證

--插入以下語句,使資料不一致
insert into mytbl values(2,@@hostname);
--通過查詢mycat表中的資料,發現查詢到的結果在node02,node03,node04之間切換,符合正常情況
select * from mytbl;
--停止node01的mysql服務
service mysqld stop
--重新插入語句
insert into mytbl values(3,@@hostname);
--開啟node01的mysql服務
service mysqld start
--執行相同的查詢語句,此時發現在noede01,node02,node04之間切換,符合情況

​ 通過上述的驗證,我們可以得到一個結論,node01,node03互做備機,負責寫的宕機切換,其他機器充作讀請求的響應。

​ 做到此處,希望大家能夠思考一個問題,在上述我們做的讀寫分離操作,其實都是基於主從複製的,也就是資料同步,但是在生產環境中會存在很多種情況造成主從複製延遲問題,那麼我們應該如何解決延遲問題,這是一個值得思考的問題,到底如何解決呢?