文章共 1796字,閱讀大約須要 4分鐘 !mysql
在現在海量數據充斥的互聯網環境下,分庫分表的意義我想在此處就不用贅述了。而分庫分表目前流行的方案最起碼有兩種:linux
而本文即將要實驗的 MyCAT框架就屬於第二種方案的表明做品。git
注: 本文首發於 My Personal Blog:CodeSheep·程序羊,歡迎光臨 小站github
在本文中,我拿出了三臺 Linux主機投入試驗,各節點的角色分配以下表所示:sql
節點 | 部署組件 | 角色 |
---|---|---|
192.168.199.75 | MySQL 、 MyCAT | master |
192.168.199.74 | MySQL | slave |
192.168.199.76 | MySQL | standby master |
若是說上面這張表不足以說明實驗模型,那接下來再給一張圖好了,以下所示:數據庫
我想這樣看來的話,各個節點布了哪些組件,節點間的角色關係應該一目瞭然了吧後端
實驗環境規劃好了之後,接下來進行具體的部署與實驗過程,首先固然是 MyCAT代理的部署框架
關於該部分,網上教程實在太多了,但最好仍是參考官方文檔來吧,下面也簡述一下部署過程學習
這裏安裝的是 MyCAT 1.5測試
wget https://raw.githubusercontent.com/MyCATApache/Mycat-download/master/1.5-RELEASE/Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz tar -zxvf Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz mv mycat /usr/local/
./mycat start
mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB
官網上對於這一部分的描述是很是詳細的,MyCAT 配置主要涉及三個 XML配置文件:
server.xml
:MyCAT框架的系統參數/用戶參數配置文件schema.xml
: MyCAT框架的邏輯庫表與分片的配置文件rule.xml
:MyCAT框架的邏輯庫表分片規則的配置文件用以下圖形能夠形象地表示出這三個 XML配置文件的配置內容和相互關係:
下面來進入具體的實驗環節 ,這也是圍繞 MyCAT提供的幾大主要功能展開的,主要涉及三個方面
實驗以前,咱們先給出公共的 server.xml
文件的配置,這部分後續實驗過程當中並不修改,其也就是定義了系統參數和用戶參數:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mycat:server SYSTEM "server.dtd"> <mycat:server xmlns:mycat="http://org.opencloudb/"> <system> <property name="defaultSqlParser">druidparser</property> <!-- <property /> 這塊諸多的property配置在此就不配置了,參照官網按需配置 --> </system> <user name="test"> <property name="password">test</property> <property name="schemas">TESTDB</property> </user> <user name="user"> <property name="password">user</property> <property name="schemas">TESTDB</property> <property name="readOnly">true</property> </user> </mycat:server>
預期實驗效果:經過 MyCAT代理往一張邏輯表中插入的多條數據,在後端自動地分配在不一樣的物理數據庫表上
咱們按照本文 **第二節【環境規劃】**中給出的實驗模型圖來給出以下的 MyCAT邏輯庫配置文件 schema.xml
和 分庫分表規則配置文件 rule.xml
schema.xml
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://org.opencloudb/" > <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> <table name="travelrecord" dataNode="dn1,dn2" rule="sharding-by-month" /> </schema> <dataNode name="dn1" dataHost="testhost" database="db1" /> <dataNode name="dn2" dataHost="testhost" database="db2" /> <dataHost name="testhost" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="localhost:3306" user="root" password="xxxxxx"> <readHost host="hostS1" url="192.168.199.74:3306" user="root" password="xxxxxx" /> </writeHost> <writeHost host="hostM2" url="192.168.199.76:3306" user="root" password="xxxxxx"> </writeHost> </dataHost> </mycat:schema>
其中定義了實驗用到的 hostM一、hostS1 和 hostM2
rule.xml
<tableRule name="sharding-by-month"> <rule> <columns>create_date</columns> <algorithm>partbymonth</algorithm> </rule> </tableRule> <function name="partbymonth" class="org.opencloudb.route.function.PartitionByMonth"> <property name="dateFormat">yyyy-MM-dd</property> <property name="sBeginDate">2018-11-01</property> </function>
這裏配置了
sharding-by-month
的分庫分表規則,即按照表中的create_date
字段進行分割,從2018-11-01
日期開始,月份不一樣的數據落到不一樣的物理數據庫表中
create database db1; create database db2;
mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB
travelrecord
create table travelrecord (id bigint not null primary key,city varchar(100),create_date DATE);
travelrecord
表中插入兩條數據insert into travelrecord(id,city,create_date) values(1,'NanJing','2018-11-3'); insert into travelrecord(id,city,create_date) values(2,'BeiJing','2018-12-3');
因爲插入的這兩條記錄的 create_date
分別是 2018-11-3
和 2018-12-3
,而咱們配的分庫分表的規則便是根據 2018-11-01
這個日期爲起始來進行遞增的,按照前面咱們配的分片規則,理論上這兩條記錄按照 create_date
日期字段的不一樣,應該分別插入到 hostM1的 db1和 db2兩個不一樣的數據庫中。
因爲 hostM1和 hostS1組成了 主-從庫 關係,所以剛插入的兩條數據也應該相應自動同步到 hostS1的 db1和 db2兩個數據庫中,不妨也來驗證一下:
**預期實驗效果:**開啓了 MyCAT的讀寫分離機制後,讀寫數據操做各行其道,互不干擾
此節實驗用到的配置文件 schema.xml
和 rule.xml
基本和上面的【分庫分表】實驗沒什麼不一樣,只是咱們須要關注一下 schema.xml
配置文件中 <dataHost />
標籤裏的 balance
字段,它是與讀寫分離息息相關的配置:
所以咱們就須要弄清楚 <dataHost /> 標籤中 balance參數的含義:
balance="0"
:不開啓讀寫分離機制,即讀請求僅分發到 writeHost上balance="1"
:讀請求隨機分發到當前 writeHost對應的 readHost和 standby writeHost上balance="2"
:讀請求隨機分發到當前 dataHost內全部的 writeHost / readHost上balance="3"
:讀請求隨機分發到當前 writeHost對應的 readHost上咱們驗證一下 balance="1"
的狀況,即開啓讀寫分離機制,且讀請求隨機分發到當前 writeHost對應的 readHost和 standby writeHost上,而對於本文來說,也即:hostS1 和 hostM2 上
咱們來作兩次數據表的 SELECT
讀操做:
mysql> select * from travelrecord limit 6; +----+----------+-------------+ | id | city | create_date | +----+----------+-------------+ | 3 | TianJing | 2018-11-04 | | 5 | ShenYang | 2018-11-05 | | 4 | Wuhan | 2018-12-04 | | 6 | Harbin | 2018-12-05 | +----+----------+-------------+ 4 rows in set (0.08 sec) mysql> select * from travelrecord limit 6; +----+---------+-------------+ | id | city | create_date | +----+---------+-------------+ | 2 | BeiJing | 2018-12-03 | | 8 | WuXi | 2018-12-06 | | 1 | NanJing | 2018-11-03 | | 7 | SuZhou | 2018-11-06 | +----+---------+-------------+ 4 rows in set (0.01 sec)
而後咱們取出 mycat.log
日誌查看一下具體詳情,咱們發現第一次 select
讀操做分發到了 hostM2
上:
而第二次 select
讀操做分發到了 hostS1
上:
**預期實驗效果:**開啓 MyCAT的主備機制後,當主庫宕機時,自動切換到備用機進行操做
關於主備切換,則須要弄清楚 <dataHost />
標籤中 switchType
參數的含義:
switchType="-1"
:不自動切換主備數據庫switchType="1"
:自動切換主備數據庫switchType="2"
:基於MySQL主從複製的狀態來決定是否切換,需修改heartbeat語句:show slave status
switchType="3"
:基於Galera(集羣多節點複製)的切換機制,需修改heartbeat語句:show status like 'wsrep%'
此處驗證一下 Mycat的主備自動切換效果。爲此首先咱們將 switchType="-1"
設置爲 switchType="1"
,並重啓 MyCat服務:
<dataHost name="testhost" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
在本實驗環境中,在 hostM1 和 hostM2均正常時,默認寫數據時是寫到 hostM1的
systemctl stop mysqld.service
接下來再經過 MyCat插入以下兩條數據:
insert into travelrecord(id,city,create_date) values(3,'TianJing','2018-11-4'); insert into travelrecord(id,city,create_date) values(4,'Wuhan','2018-12-4');
效果以下:
insert into travelrecord(id,city,create_date) values(5,'ShenYang','2018-11-5'); insert into travelrecord(id,city,create_date) values(6,'Harbin','2018-12-5');
再插入兩條數據:
insert into travelrecord(id,city,create_date) values(7,'SuZhou','2018-11-6'); insert into travelrecord(id,city,create_date) values(8,'WuXi','2018-12-6');
很明顯,答案是確定的
因爲能力有限,如有錯誤或者不當之處,還請你們批評指正,一塊兒學習交流!