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互做備機,負責寫的宕機切換,其他機器充作讀請求的響應。
做到此處,希望大家能夠思考一個問題,在上述我們做的讀寫分離操作,其實都是基於主從複製的,也就是資料同步,但是在生產環境中會存在很多種情況造成主從複製延遲問題,那麼我們應該如何解決延遲問題,這是一個值得思考的問題,到底如何解決呢?