資料庫讀寫分離對于大型系統或者通路量很高的網際網路應用來說,是必不可少的一個重要功能。對于MySQL來說,标準的讀寫分離是主從模式,一個寫節點Master後面跟着多個讀節點,讀節點的數量取決于系統的壓力,通常是1-3個讀節點的配置。
Mycat讀寫分離和自動切換機制,需要mysql的主從複制機制配合。
- MyCat的安裝請參考:Linux 下 Mycat 的安裝配置
- Mysql主從複制的配置請參考:MySql 主從複制的配置(GTID 方式)
一、MyCat 的配置
從 Mycat 1.4 開始支援MySQL主從複制狀态綁定的讀寫分離機制,讓讀更加安全可靠,配置如下:
配置檔案的意思是:
- 邏輯庫:small。邏輯表:tb_item;
- Master伺服器上建立了一個資料庫:db1;
- Slave伺服器同步Master伺服器的 db1 資料庫;
- 寫請求都發送到Master伺服器;
- 讀請求都發送到Slave伺服器。
[[email protected] conf]# vim schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="small" checkSQLschema="false" sqlMaxLimit="100">
<table name="tb_item" dataNode="dn1" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM" url="mysql-server-01:3306" user="root" password="888888">
<readHost host="hostS" url="mysql-server-02:3306" user="root" password="888888" />
</writeHost>
</dataHost>
</mycat:schema>
二、測試
1、我們使用 Navicat 連接配接 MyCat 伺服器
2、建立表
執行如下建表語句,執行之後可以看到Master伺服器上的資料庫 db1 中存在了 tb_item 表。再看看Slave伺服器上的 db1 資料庫中也存在了 tb_item 表。
-- ----------------------------
-- Table structure for tb_item
-- ----------------------------
DROP TABLE IF EXISTS `tb_item`;
CREATE TABLE `tb_item` (
`id` bigint(20) NOT NULL COMMENT '商品id,同時也是商品編号',
`title` varchar(100) NOT NULL COMMENT '商品标題',
`sell_point` varchar(500) DEFAULT NULL COMMENT '商品賣點',
`price` bigint(20) NOT NULL COMMENT '商品價格,機關為:分',
`num` int(10) NOT NULL COMMENT '庫存數量',
`barcode` varchar(30) DEFAULT NULL COMMENT '商品條形碼',
`image` varchar(500) DEFAULT NULL COMMENT '商品圖檔',
`cid` bigint(10) NOT NULL COMMENT '所屬類目,葉子類目',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '商品狀态,1-正常,2-下架,3-删除',
`created` datetime NOT NULL COMMENT '建立時間',
`updated` datetime NOT NULL COMMENT '更新時間',
PRIMARY KEY (`id`),
KEY `cid` (`cid`),
KEY `status` (`status`),
KEY `updated` (`updated`)
) COMMENT='商品表';
3、從插入資料
INSERT INTO TB_ITEM (
ID,
TITLE,
SELL_POINT,
PRICE,
NUM,
BARCODE,
IMAGE,
CID,
STATUS,
CREATED,
UPDATED
)
VALUES
(
'15000000',
'夏普(SHARP)LCD-52DS51A 52英寸 日本原裝液晶面闆 内置WIFI智能全高清液晶電視',
'要好屏,選夏普!日本原裝面闆,智能電視,高畫質高音質!<a target=\"blank\" href=\"http://item.jd.com/1278664.html\">還有更新版安卓智能新機52DS52供您選擇!</a>',
'549900',
'99999',
NULL,
'http://image.taotao.com/jd/63af01c37a18454ab2fef4670046272e.jpg',
'76',
'1',
'2015-03-08 21:27:45',
'2015-03-08 21:27:45'
);
4、測試讀寫分離
附 1、讀寫分離的第二種配置方式
1、讀寫分離的第二種配置方式
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="small" checkSQLschema="false" sqlMaxLimit="100">
<table name="tb_item" dataNode="dn1" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="mysql-server-01:3306" user="root" password="888888"></writeHost>
<writeHost host="hostS1" url="mysql-server-02:3306" user="root" password="888888"></writeHost>
</dataHost>
</mycat:schema>
以上兩種配置方式,第一種當寫挂了讀不可用,第二種可以繼續使用。另外,事務内部的一切操作都會走寫節點,是以讀操作不要加事務。
2、強制走寫或讀節點
如果讀延時較大,我們可以使用MyCat注解的方式強制走寫節點。
繼續上面測試部分的第四小節:測試讀寫分離。接下來測試MyCat的注解方式。
圖中可能看不清楚,強制走寫節點的語句如下:
/*#mycat:db_type=master*/ SELECT * FROM tb_item ;
另外,測試時發現強制走讀節點失敗,不知道為什麼,也沒有深究(實在沒有多少時間):
/*#mycat:db_type=slave*/ SELECT * FROM tb_item ;
附 2、根據主從延時切換
1、根據主從延時切換的配置
1.4 開始支援 MySQL 主從複制狀态綁定的讀寫分離機制,讓讀更加安全可靠,配置如下:
- MyCAT 心跳檢查語句配置為 show slave status ;
- dataHost 上定義兩個新屬性:
和switchType="2"
,此時意味着開啟 MySQL 主從複制狀态綁定的讀寫分離與切換機制;slaveThreshold="100"
Mycat 心跳機制通過檢測 show slave status 中的
"Seconds_Behind_Master"
,
"Slave_IO_Running"
,
"Slave_SQL_Running"
三個字段來确定目前主從同步的狀态以及 Seconds_Behind_Master 主從複制時延。當
Seconds_Behind_Master > slaveThreshold
時,讀寫分離篩選器會過濾掉此 Slave 機器,防止讀到很久之前的舊資料。而當主節點當機後,切換邏輯會檢查 Slave 上的 Seconds_Behind_Master 是否為 0,為 0 時則表示主從同步,可以安全切換,否則不會切換。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="small" checkSQLschema="false" sqlMaxLimit="100">
<table name="tb_item" dataNode="dn1" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0"
dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>show slave status </heartbeat>
<writeHost host="hostM1" url="mysql-server-01:3306" user="root" password="888888"></writeHost>
<writeHost host="hostS1" url="mysql-server-02:3306" user="root" password="888888"></writeHost>
</dataHost>
</mycat:schema>
2、測試
将主節點(寫節點)停止,再插入一條資料,可以看到是可以插入的,此時寫節點已經關閉,讀節點出現了倆條資料:
另外,注意:将主節點重新啟動,MyCat 不會重新将其加入進來。(已親自試驗)
官方文檔中有這麼一段:
writeType="0", 所有寫操作發送到配置的第一個 writeHost,第一個挂了切到還生存的第二個
writeHost,重新啟動後已切換後的為準,切換記錄在配置檔案中:dnindex.properties .