MyCAT的架構以下圖所示:
html
MyCAT使用MySQL的通信協議模擬成一個MySQL服務器,並創建了完整的Schema(數據庫)、Table(數據表)、User(用戶)的邏輯模型,並將這套邏輯模型映射到後端的存儲節點DataNode(MySQL Instance)上的真實物理庫中,這樣一來,全部能使用MySQL的客戶端以及編程語言都能將MyCAT當成是MySQLServer來使用,沒必要開發新的客戶端協議。java
當MyCAT收到一個客戶端發送的SQL請求時,會先對SQL進行語法分析和檢查,分析的結果用於SQL路由,SQL路由策略支持傳統的基於表格的分片字段方式進行分片,也支持獨有的基於數據庫E-R關係的分片策略,對於路由到多個數據節點(DataNode)的SQL,則會對收到的數據集進行「歸併」而後輸出到客戶端。node
SQL執行的過程,簡單的說,就是把SQL經過網絡協議發送給後端的真正的數據庫上進行執行,對於MySQL Server來講,是經過MySQL網絡協議發送報文,並解析返回的結果,若SQL不涉及到多個分片節點,則直接返回結果,寫入客戶端的SOCKET流中,這個過程是非阻塞模式(NIO)。mysql
DataNode是MyCAT的邏輯數據節點,映射到後端的某一個物理數據庫的一個Database,爲了作到系統高可用,每一個DataNode能夠配置多個引用地址(DataSource),當主DataSource被檢測爲不可用時,系統會自動切換到下一個可用的DataSource上,這裏的DataSource便可認爲是Mysql的主從服務器的地址。linux
與任何一個傳統的關係型數據庫同樣,MyCAT也提供了「數據庫」的定義,並有用戶受權的功能,下面是MyCAT邏輯庫相關的一些概念:sql
MyCAT目前經過配置文件的方式來定義邏輯庫和相關配置:shell
· MYCAT_HOME/conf/schema.xml中定義邏輯庫,表、分片節點等內容;數據庫
· MYCAT_HOME/conf/rule.xml中定義分片規則;express
· MYCAT_HOME/conf/server.xml中定義用戶以及系統相關變量,如端口等。apache
下圖給出了MyCAT一個可能的邏輯庫到物理庫(MySQL的完整映射關係),能夠看出強大的分片能力以及靈活的Mysql集羣整合能力。
MyCAT使用Java開發,由於用到了JDK 7的部分功能,因此在使用前請確保安裝了JDK 7.0,要求是JDK 7.0以上,並設置了正確的Java環境變量
目前下載的版本是免安裝,解壓在任意磁盤、根目錄下,避免路徑中出現中文。
目錄下的「Mycat-server-1.2-GA-win.tar.gz」文件,解壓後的目錄結構以下圖所示:
目錄說明見下表所示:
目錄名稱 |
說明 |
bin |
存放window版本和linux版本,除了提供封裝成服務的版本以外,也提供nowrap的shell腳本命令,方便你們選擇和修改。 Windows 下 運行:mycat.bat console在控制檯啓動程序,也能夠裝載成服務,若此程序運行有問題,也能夠運行startup_nowrap.bat,確保java命令能夠在命令執行。 Warp方式的命令,能夠安裝成服務並啓動或中止。 l mycat install (可選) l mycat start 注意,wrap方式的程序,其JVM配置參數在conf/wrap.conf中,能夠修改成合適的參數,參數調整參照http://wrapper.tanukisoftware.com/doc/english/properties.html。 |
conf |
存放配置文件: l server.xml:是Mycat服務器參數調整和用戶受權的配置文件。 l schema.xml:是邏輯庫定義和表以及分片定義的配置文件。 l rule.xml:是分片規則的配置文件,分片規則的具體一些參數信息單獨存放爲文件,也在這個目錄下,配置文件修改,須要重啓MyCAT或者經過9066端口reload。 l wrapper.conf:JVM配置參數等設置。 l log4j.xml:日誌存放在logs/mycat.log中,天天一個文件,日誌的配置是在conf/log4j.xml中,根據本身的須要,能夠調整輸出級別爲debug,debug級別下,會輸出更多的信息,方便排查問題。 |
lib |
MyCAT自身的jar包或依賴的jar包的存放目錄。 |
logs |
MyCAT日誌的存放目錄。日誌存放在logs/mycat.log中,天天一個文件 |
安裝mycat服務 :mycat install
啓動mycat服務 :mycat start
中止mycat服務 :mycat stop
注意:當修改配置文件後,須要重啓mycat服務
本地 mycat 192.168.1.5
服務器A mysql 192.168.1.201
服務器A mysql 192.168.1.202
安裝MySQL服務器和MySQL客戶端,筆者使用的MySQL服務器是免安裝版本:mysql-noinstall-5.1.73-winx64,MySQL客戶端是:Navicat for MySQL,免安裝版本安裝方法請參考:http://blog.csdn.net/q98842674/article/details/12094777
3.2 建立數據庫
分別在服務器A、服務器B建立所用的分片數據庫;
CREATE database db1;
schema.xml配置文件,由於分庫在不一樣的服務器,所以配置兩個datahost;若是在一個datahost中配置多個writeHost,則爲主從配置。type="global"時,爲全局表,
server.xml配置文件,本實例很簡單,就只定義user,
name:用戶名
password:密碼
schemas:實例名,和schema.xml定義的schema對應,這裏的實例名是虛擬名,也就是對mycat服務的一種別名,是 應用程序以及客戶端鏈接的入口。
3.4 登陸mycat
在任意有mysql的客戶端的機器鏈接Mycat, 執行如下命令
mysql -utest -ptest -h192.168.1.5 -P8066 -DTESTDB 注意:8066登陸mycat數據端口,9066登陸mycat管理端口(能看到mycat內的配置、以及各個數據庫鏈接狀況,頗有用)
3.5 測試
全局表:company
mysql> create table company(id int not null primary key,name varchar(100),sharding_id int not null);
Query OK, 0 rows affected (0.30 sec)
mysql> explain create table company(id int not null primary key,name varchar(100),sharding_id int not null);
+-----------+------------------------------------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+------------------------------------------------------------------------------------------------+
| dn1 | create table company(id int not null primary key,name varchar(100),sharding_id int not null) |
| dn2 | create table company(id int not null primary key,name varchar(100),sharding_id int not null) |
+-----------+------------------------------------------------------------------------------------------------+
2 rows in set (0.04 sec)
mysql> insert into company(id,name,sharding_id) values(1,'leader us',10000);
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 6
Current database: TESTDB
Query OK, 1 row affected (0.03 sec)
mysql> explain insert into company(id,name,sharding_id) values(1,'leader us',10000);
+-----------+-----------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+-----------------------------------------------------------------------+
| dn1 | insert into company(id,name,sharding_id) values(1,'leader us',10000) |
+-----------+-----------------------------------------------------------------------+
1 row in set (0.00 sec)
水平分表:travelrecord
mysql> explain create table travelrecord(id int not null primary key,name varchar(100));
+-----------+---------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+---------------------------------------------------------------------+
| dn1 | create table travelrecord(id int not null primary key,name varchar(100)) |
| dn2 | create table travelrecord(id int not null primary key,name varchar(100)) |
| dn3 | create table travelrecord(id int not null primary key,name varchar(100)) |
+-----------+---------------------------------------------------------------------+
3 rows in set (0.01 sec)
(7) 三個分片上都插入了3條數據
mysql> explain insert into travelrecord(id,name) values(1,'hp');
+-----------+---------------------------------------------+
| DATA_NODE | SQL |
+-----------+---------------------------------------------+
| dn1 | insert into travelrecord(id,name) values(1,'hp') |
| dn2 | insert into travelrecord(id,name) values(1,'hp') |
| dn3 | insert into travelrecord(id,name) values(1,'hp') |
+-----------+---------------------------------------------+
3 rows in set (0.00 sec)
-------------------------------------