MySQL中間件之MyCat

MySQL中間件之MyCat

1、MyCat基礎概念

一、什麼是MyCat

一個完全開源的,面向企業應用開發的大數據庫集羣
支持事務、ACID、能夠替代MySQL的增強版數據庫
一個能夠視爲MySQL集羣的企業級數據庫,用來替代昂貴的Oracle集羣
一個融合內存緩存技術、NoSQL技術、HDFS大數據的新型SQL Server
結合傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品
一個新穎的數據庫中間件產品java

二、爲何使用MyCat

現在隨着互聯網的發展,數據的量級也是撐指數的增加,從GB到TB到PB。對數據的各類操做也是越發的困難,傳統的關係性數據庫已經沒法知足快速查詢與插入數據的需求。這個時候NoSQL的出現暫時解決了這一危機。它經過下降數據的安全性,減小對事務的支持,減小對複雜查詢的支持,來獲取性能上的提高。可是,在有些場合NoSQL一些折衷是沒法知足使用場景的(好比有些使用場景是絕對要有事務與安全指標的。這個時候NoSQL確定是沒法知足的)。因此仍是須要使用關係性數據庫。如何使用關係型數據庫解決海量存儲的問題呢?此時就須要作數據庫集羣,爲了提升查詢性能將一個數據庫的數據分散到不一樣的數據庫中存儲,爲應對此問題就出現了——MyCatnode

MyCat做用:

能知足數據庫數據大量存儲;提升了查詢性能
讀寫分離
數據分片 垂直拆分(分庫)、水平拆分(分表)、垂直+水平拆分(分庫分表)
多數據源整合mysql

三、 數據庫中間件對比

① Cobar(前身爲amoaba)屬於阿里B2B事業羣,始於2008年,在阿里服役3年多,接管3000+個MySQL數據庫的schema, 集羣日處理在線SQL請求50億次以上。因爲Cobar發起人的離職, Cobar中止維護。
② Mycat是開源社區在阿里cobar基礎上進行二次開發,解決了cobar存在的問題,而且加入了許多新 的功能在其中。青出於藍而勝於藍。
③ OneProxy基於MySQL官方的proxy思想利用c進行開發的, OneProxy是一款商業收費的中間件。捨棄了一些功能,專一在性能和穩定性上。
④ kingshard由小團隊用go語言開發,還須要發展,須要不斷完善。
⑤ Vitess是Youtube生產在使用,架構很複雜。不支持MySQL原生協議,使用須要大量改形成本。
⑥ Atlas是360團隊基於mysql proxy改寫,功能還需完善,高併發下不穩定。
⑦ MaxScale是mariadb(MySQL原做者維護的一個版本) 研發的中間件
⑧ MySQLRoute是MySQL官方Oracle公司發佈的中間件linux

四、支持的數據庫

支持MySQL ORACLE SQLServer等一些主流的數據庫算法

五、核心技術

分庫分表:數據庫分片指經過某種特定的條件,將咱們存放在一個數據庫中的數據分散存放在不一樣的多個數據庫(主機)中,這樣來達到分散單臺設備的負載,根據切片規則,可分爲如下兩種切片模式,MyCAT經過定義表的分片規則來實現分片,每一個表格能夠捆綁一個分片規則,每一個分片規則指定一個分片字段並綁定一個函數,來實現動態分片算法sql

1)Schema:邏輯庫,與MySQL中的Database(數據庫)對應,一個邏輯庫中定義了所包括的Table。
2)Table:邏輯表,即物理數據庫中存儲的某一張表,與傳統數據庫不一樣,這裏的表格須要聲明其所存儲的邏輯數據節點DataNode。在此能夠指定表的分片規則。
3)DataNode:MyCAT的邏輯數據節點,是存放table的具體物理節點,也稱之爲分片節點,經過DataSource來關聯到後端某個具體數據庫上
4)DataSource:定義某個物理庫的訪問地址,用於捆綁到Datanode上
5)分片規則:前面講了數據切分,一個大表被分紅若干個分片表,就須要必定的規則,這樣按照某種業務規則把數據分到某個分片的規則就是分片規則,數據切分選擇合適的分片規則很是重要,將極大的避免後續數據處理的難數據庫

2、MyCat安裝部署

環境:

JDK:要求jdk必須是1.7及以上版本
MySQL:推薦mysql是5.5以上版本
MyCat的官方網站:http://www.mycat.org.cn/
主機 操做系統 IP地址
mysql01(master01) CentOS 7.3 192.168.1.1
mysql02(slave) CentOS 7.3 192.168.1.8
mycat CentOS 7.3 192.168.1.3
PS:mysql使用現成的主機(搭建了雙主+keepalived,主從也能夠)。若是沒有mysql,看上一個博客部署。

一、下載及安裝,使用上面的官網地址下載。

MySQL中間件之MyCat
MySQL中間件之MyCat

複製連接,wget下載vim

[root@localhost ~]# wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

MySQL中間件之MyCat

將壓縮包解壓縮。建議將mycat放到/usr/local/mycat目錄下。後端

[root@localhost ~]# tar zxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
[root@localhost ~]# cd mycat/

修改配置文件:緩存

server.xml: 定義用戶以及系統相關變量,如端口等
schema.xml: 定義邏輯庫,表、分片節點等內容
rule.xml: 定義分片規則

[root@mycat mycat]# vim conf/server.xml  
80         <user name="mycat">      //定義鏈接中間件的用戶
81                 <property name="password">123456</property>  //密碼
82                 <property name="schemas">TESTDB</property>      //邏輯庫
[root@mycat mycat]# cp conf/schema.xml conf/schema.xml.bak  //備份配置文件
[root@mycat mycat]# vim conf/schema.xml 
<?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="test_db" />     //指定後端服務器中的真實庫
        <dataHost name="host1" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="192.168.1.1:3306" user="root"    //定義寫的服務器(主)以及IP地址,用戶密碼
                                   password="123.com">
                        <!-- can have multi read hosts -->
                        <readHost host="hostS2" url="192.168.1.8:3306" user="root" password="123.com" />    //定義讀的服務器(從)以及IP地址,用戶密碼
                </writeHost>
        </dataHost>
</mycat:schema>

##這個配置文件已經把沒必要要配置項以及註釋的都刪了

重啓mycat服務
讓mycat擁有mysql命令

[root@mysql02 ~]# scp /usr/local/mysql/bin/mysql 192.168.1.3:/usr/local/sbin/

兩臺mysql受權,容許mycat遠程登錄

mysql> grant all on *.* to root@'192.168.1.%' identified by '123.com';

MyCat遠程登陸測試:

[root@mycat mycat]# mysql -uroot -h 192.168.1.1 -P 3306 -p123.com
[root@mycat mycat]# mysql -uroot -h 192.168.1.8 -P 3306 -p123.com

啓動mycat服務:

[root@mycat mycat]# ./bin/mycat help
Usage: ./bin/mycat { console | start | stop | restart | status | dump }
[root@mycat mycat]# ./bin/mycat console

使用console啓動,會佔用一個終端,實時查看日誌內容(登陸、查詢、退出),使用start啓動不會又實時日誌,不佔用終端

[root@mycat ~]# ss -anplt |grep java

MySQL中間件之MyCat
###mycat端口8806

測試,查看數據是否同步:

[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> show databases;

MySQL中間件之MyCat

mysql> use TESTDB
mysql> show tables;

MySQL中間件之MyCat

mysql> select * from tab1;

MySQL中間件之MyCat

3、MyCat讀寫分離

Mycat的讀寫分離是創建在Mysql的主從複製的基礎上的

修改配置文件 schema.xml

[root@mycat ~]# cd mycat/
[root@mycat mycat]# vim conf/schema.xml

一、設置balance="1"與writeType="0"

Balance參數設置:
    修改的balance屬性,經過此屬性配置讀寫分離的類型負載均衡類型,目前的取值有4 種: 
   balance="0",不開啓讀寫分離機制, 全部讀操做都發送到當前可用的 writeHost 上。 
   balance="1",所有的 readHost與 stand by writeHost 參與 select 語句的負載均衡,簡單的說,當雙主雙從模式(M1->S1, M2->S2,而且M1與M2 互爲主備),正常狀況下, M2,S1,S2 都參與 select 語句的負載均衡。
   balance="2",全部讀操做都隨機的在 writeHost、 readhost 上分發。
   balance="3",全部讀請求隨機的分發到 readhost 執行,writerHost 不負擔讀壓力
WriteType參數設置:
   writeType=「0」, 全部寫操做都發送到可用的writeHost上。
   writeType=「1」,全部寫操做都隨機的發送到readHost。
   writeType=「2」,全部寫操做都隨機的在writeHost、readhost分上發。

「readHost是從屬於writeHost的,即意味着它從那個writeHost獲取同步數據,所以,當它所屬的writeHost宕機了,則它也不會再參與到讀寫分離中來,即「不工做了」,這是由於此時,它的數據已經「不可靠」了。基於這個考慮,目前mycat 1.3和1.4版本中,若想支持MySQL一主一從的標準配置,而且在主節點宕機的狀況下,從節點還能讀取數據,則須要在Mycat裏配置爲兩個writeHost並設置banlance=1。」

二、設置switchType="2" 與slaveThreshold="100"

switchType 目前有三種選擇:
   -1:表示不自動切換
   1 :默認值,自動切換
   2 :基於MySQL主從同步的狀態決定是否切換

「Mycat心跳檢查語句配置爲 show slave status ,dataHost 上定義兩個新屬性: switchType="2" 與slaveThreshold="100",此時意味着開啓MySQL主從複製狀態綁定的讀寫分離與切換機制。Mycat心跳機制經過檢測 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三個字段來
肯定當前主從同步的狀態以及Seconds_Behind_Master主從複製時延。

三、修改配置文件,啓動程序

[root@mycat mycat]# vim conf/schema.xml

MySQL中間件之MyCat

①控制檯啓動:mycat/bin 目錄下執行 ./mycat console
②後臺啓動:mycat/bin 目錄下./mycat start
爲了能第一時間看到啓動日誌,方便定位問題,選擇①控制檯啓動。

[root@mycat mycat]# ./bin/mycat console

登陸後臺管理窗口 此登陸方式用於管理維護 Mycat

[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066

四、驗證讀寫分離 my.cnf binlog_format=STATEMENT

(1) 在寫主機插入數據:

[root@mysql02 ~]# mysql -uroot -p123.com
mysql> use test1;
mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.01 sec)

mysql> insert into tab1 values(4);
Query OK, 1 row affected (0.02 sec)

mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
4 rows in set (0.00 sec)

主從主機數據不一致了

[root@mysql01 ~]# mysql -uroot -p123.com
mysql> use test1
mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

(2) 在Mycat裏查詢:

mysql> use TESTDB
mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
4 rows in set (0.00 sec)

4、垂直拆分--分庫

一個數據庫由不少表的構成,每一個表對應着不一樣的業務,垂直切分是指按照業務將表進行分類, 分佈到不一樣 的數據庫上面,這樣也就將數據或者說壓力分擔到不一樣的庫
如何劃分表分庫的原則:有緊密關聯關係的表應該在一個庫裏,相互沒有關聯關係的表能夠分到不一樣的庫裏。

這個案例中須要一臺新的mysql來進行分庫操做。

主機 操做系統 IP地址
mysql01(master01) CentOS 7.3 192.168.1.1
mysql02(slave) CentOS 7.3 192.168.1.8
mycat CentOS 7.3 192.168.1.3
mysql03(master02) CentOS 7.3 192.168.1.9

先將上一個案例插入的數據刪除

[root@mysql02 ~]# mysql -uroot -p123.com
mysql> delete from tab1 where id=4;
Query OK, 1 row affected (0.01 sec)

mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> use TESTDB

mysql> select * from tab1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

以下四個表:
客戶表分在一個數據庫,另外三張都須要關聯查詢,分在另一個數據庫。

#客戶表 rows:20萬
CREATE TABLE customer(
id INT AUTO_INCREMENT,
NAME VARCHAR(200),
PRIMARY KEY(id)
);
#訂單表 rows:600萬
CREATE TABLE orders(
id INT AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id)
);
#訂單詳細表 rows:600萬
CREATE TABLE orders_detail(
id INT AUTO_INCREMENT,
detail VARCHAR(2000),
order_id INT,
PRIMARY KEY(id)
);
#訂單狀態字典表 rows:20
CREATE TABLE dict_order_type(
id INT AUTO_INCREMENT,
order_type VARCHAR(200),
PRIMARY KEY(id)
);

實現分庫:

一、 修改 schema 配置文件

[root@mycat mycat]# vim conf/schema.xml

MySQL中間件之MyCat

<?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">
                <table name="customer" dataNode="dn2"> </table>
        </schema> 
        <dataNode name="dn1" dataHost="host1" database="test1" />
        <dataNode name="dn2" dataHost="host2" database="test1" />
        <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.1.1:3306" user="root"
                                   password="123.com">
                        <readHost host="hostS2" url="192.168.1.8:3306" user="root" password="123.com" />
                </writeHost>
        </dataHost> 
        <dataHost name="host2" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM2" url="192.168.1.9:3306" user="root"
                                   password="123.com">
                </writeHost> 
        </dataHost>

</mycat:schema>

受權MyCat遠程登錄mysql03

[root@mysql03 ~]# mysql -uroot -p123.com
mysql> grant all on *.* to root@'192.168.1.%' identified by '123.com';

由於在配置文件中邏輯庫所對應的真實庫mysql03中並無,須要在mysql03中建立

mysql> create database test1;

二、 重啓mycat,訪問MyCat,建立表

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066

mysql> use TESTDB
mysql> CREATE TABLE customer(
    -> id INT AUTO_INCREMENT,
    -> NAME VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE orders(
    -> id INT AUTO_INCREMENT,
    -> order_type INT,
    -> customer_id INT,
    -> amount DECIMAL(10,2),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE orders_detail(
    -> id INT AUTO_INCREMENT,
    -> detail VARCHAR(2000),
    -> order_id INT,
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE dict_order_type(
    -> id INT AUTO_INCREMENT,
    -> order_type VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
+-----------------     +
| Tables_in_test1 |
+-----------------     +
| customer           |
| dict_order_type |
| orders               |
| orders_detail    |
| tab1                  |
+-----------------    +
5 rows in set (0.05 sec)

使用mysql01查看錶:

mysql> show tables;
+-----------------    +
| Tables_in_test1 |
+-----------------    +
| dict_order_type |
| orders               |
| orders_detail    |
| tab1                  |
+-----------------    +
4 rows in set (0.00 sec)

使用mysql03查看錶:

mysql> use test1;
mysql> show tables;
+-----------------     +
| Tables_in_test1 |
+-----------------     +
| customer           |
+-----------------     +
1 row in set (0.00 sec)

查看結構

mysql> desc customer;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id          | int(11)           | NO    | PRI | NULL    | auto_increment |
| NAME  | varchar(200) | YES  |     | NULL       |                |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

5、水平拆分--分表

相對於垂直拆分,水平拆分不是將表作分類,而是按照某個字段的某種規則來分散到多個庫之中, 每一個表中 包含一部分數據。簡單來講,咱們能夠將數據的水平切分理解爲是按照數據行的切分,就是將表中的某些行切分到一個數據庫,而另外的某些行又切分到其餘的數據庫中。
實現分表 選擇要拆分的表 MySQL 單表存儲數據條數是有瓶頸的,單表達到 1000 萬條數據就達到了瓶頸,會影響查詢效率,須要進行水平拆分(分表)進行優化。 例如:上一案例的 orders、orders_detail 都已經達到600 萬行數據,須要進行分表優化。 分表字段以 orders 表爲例,能夠根據不一樣自字段進行分表

編號 分表字段 效果
1 id(主鍵、或建立時間) 查詢訂單注重時效,歷史訂單被查詢的次數少,如此分片會形成一個節點訪問多,一個訪問少,不平均。
2 customer_id(客戶ID) 根據客戶 id 去分,兩個節點訪問平均,一個客戶的全部訂單都在同一個節點

一、修改配置文件 schema.xml

[root@mycat mycat]# vim conf/schema.xml

MySQL中間件之MyCat

<?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">
                <table name="customer" dataNode="dn2"> </table>
                <table name="orders" dataNode="dn1,dn2" rule="mod_rule">
                        <childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
                </table>
        </schema> 
        <dataNode name="dn1" dataHost="host1" database="test1" />
        <dataNode name="dn2" dataHost="host2" database="test1" />
        <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.1.1:3306" user="root"
                                   password="123.com">
                        <readHost host="hostS2" url="192.168.1.8:3306" user="root" password="123.com" />
                </writeHost>
        </dataHost> 
        <dataHost name="host2" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM2" url="192.168.1.9:3306" user="root"
                                   password="123.com">
                </writeHost> 
        </dataHost>

二、修改配置文件rule.xml

[root@mycat mycat]# vim conf/rule.xml

#在 rule 配置文件裏新增分片規則 mod_rule,並指定規則適用字段爲 customer_id,
#還有選擇分片算法 mod-long(對字段求模運算) , customer_id 對兩個節點求模,根據結果分片

38         <tableRule name="mod_rule">
 39                 <rule>
 40                         <columns>customer_id</columns>
 41                         <algorithm>mod-long</algorithm>
 42                 </rule>
 43         </tableRule>
 ……
 105         <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
 106                 <!-- how many data nodes -->
 107                 <property name="count">2</property>
#配置算法 mod-long 參數 count 爲 2,兩個節點
 108         </function>

三、由於在dn2(mysql03:192.168.1.9)上並無orders表,在數據節點dn2上建立orders表,並重啓mycat服務

[root@mysql03 ~]# mysql -uroot -p123.com
mysql> use test1;
mysql> CREATE TABLE orders(
    -> id INT AUTO_INCREMENT,
    -> order_type INT,
    -> customer_id INT,
    -> amount DECIMAL(10,2),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.00 sec)

四、在MyCat中向orders表插入數據,insert字段不能省略

[root@mycat mycat]# mysql -umycat -p123456 -P8066 -h192.168.1.3
mysql> use TESTDB

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES (1,101,100,100100);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(2,101,100,100300);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(3,101,101,120000);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(4,101,101,103000);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(5,102,101,100400);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(6,102,100,100020);
Query OK, 1 row affected (0.01 sec)

#在mycat、dn一、dn2中查看orders表數據,分表成功
MySQL中間件之MyCat

dn1(mysql01:192.168.1.1):

[root@mysql01 ~]# mysql -uroot -p123.com
mysql> use test1;
mysql> select * from orders;
+----+------------+-------------+-----------+
| id | order_type | customer_id | amount    |
+----+------------+-------------+-----------+
|  2 |        101 |         100 | 100300.00 |
|  4 |        101 |         101 | 103000.00 |
|  6 |        102 |         100 | 100020.00 |
+----+------------+-------------+-----------+
3 rows in set (0.00 sec)

dn2(mysql03:192.168.1.9):

[root@mysql03 ~]# mysql -uroot -p123.com
mysql> use test1;

mysql> select * from orders;
+----+------------+-------------+-----------+
| id | order_type | customer_id | amount    |
+----+------------+-------------+-----------+
|  1 |        101 |         100 | 100100.00 |
|  3 |        101 |         101 | 120000.00 |
|  5 |        102 |         101 | 100400.00 |
+----+------------+-------------+-----------+
3 rows in set (0.00 sec)

在dn2(mysql03:192.168.1.9) 建立 orders_detail 表

mysql> CREATE TABLE orders_detail(
    -> id INT AUTO_INCREMENT,
    -> detail VARCHAR(2000),
    -> order_id INT,
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.02 sec)

重啓 Mycat 訪問 Mycat 向 orders_detail 表插入數據

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> use TESTDB
mysql> insert into orders_detail(id,detail,order_id) values (1,'detail',1);
Query OK, 1 row affected (0.03 sec)

mysql> insert into orders_detail(id,detail,order_id) values (2,'detail',2);
Query OK, 1 row affected (0.00 sec)

mysql> insert into orders_detail(id,detail,order_id) values (3,'detail',3);
Query OK, 1 row affected (0.01 sec)

mysql> insert into orders_detail(id,detail,order_id) values (4,'detail',4);
Query OK, 1 row affected (0.01 sec)

mysql> insert into orders_detail(id,detail,order_id) values (5,'detail',5);
Query OK, 1 row affected (0.00 sec)

mysql> insert into orders_detail(id,detail,order_id) values (6,'detail',6);
Query OK, 1 row affected (0.01 sec)

mysql> select o.*,od.detail from orders as o inner join orders_detail as od on o.id=od.order_id;
+----+------------+-------------+-----------+--------+
| id | order_type | customer_id | amount    | detail |
+----+------------+-------------+-----------+--------+
|  1 |        101 |         100 | 100100.00 | detail |
|  3 |        101 |         101 | 120000.00 | detail |
|  5 |        102 |         101 | 100400.00 | detail |
|  2 |        101 |         100 | 100300.00 | detail |
|  4 |        101 |         101 | 103000.00 | detail |
|  6 |        102 |         100 | 100020.00 | detail |
+----+------------+-------------+-----------+--------+
6 rows in set (0.03 sec)

使用dn一、dn2查看:

mysql> select * from orders_detail;

MySQL中間件之MyCat

mysql> select * from orders_detail;

MySQL中間件之MyCat

6、全局表

在分片的狀況下,當業務表由於規模而進行分片之後,業務表與這些附屬的字典表之間的關聯,就成了比較棘手的問題,考慮到字典表具備如下幾個特性:

變更不頻繁 
數據量整體變化不大 
數據規模不大,不多有超過數十萬條記錄

鑑於此, Mycat 定義了一種特殊的表,稱之爲「全局表」,全局表具備如下特性:

全局表的插入、更新操做會實時在全部節點上執行,保持各個分片的數據一致性
全局表的查詢操做,只從一個節點獲取 
全局表能夠跟任何一個表進行 JOIN 操做 將字典表或者符合字典表特性的一些表定義爲全局表,則從另一個方面,很好的解決了數據 JOIN 的難題。

經過全局表+基於 E-R 關係的分片策略, Mycat 能夠知足 80%以上的企業應用開發

[root@mycat mycat]# vim conf/schema.xml

MySQL中間件之MyCat

<table name="dict_order_type" dataNode="dn1,dn2" type="global"> </table>

在dn2(mysql03:192.168.1.9)建立dict_order_type表

mysql> CREATE TABLE dict_order_type(
    -> id INT AUTO_INCREMENT,
    -> order_type VARCHAR(200),
    -> PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

重啓MyCat,訪問MyCat向dict_order_type表插入數據

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066
mysql> use TESTDB

mysql>  insert into dict_order_type (id,order_type) values (101,'type1');
Query OK, 1 row affected (0.03 sec)

mysql>  insert into dict_order_type (id,order_type) values (102,'type2');
Query OK, 1 row affected (0.01 sec)

mysql> select * from dict_order_type;
+-----+------------+
| id  | order_type |
+-----+------------+
| 101 | type1      |
| 102 | type2      |
+-----+------------+
2 rows in set (0.03 sec)

經常使用分片規則

取模:此規則爲對分片字段求摸運算。 也是水平分表最經常使用規則。 5.1 配置分表中, orders 表採用了此規則。 分片枚舉:經過在配置文件中配置可能的枚舉 id,本身配置分片,本規則適用於特定的場景,好比有些業務 須要按照省份或區縣來作保存,而全國省份區縣固定的,這類業務使用本條規則。

相關文章
相關標籤/搜索