Mycat水平拆分之十種分片規則:
http://www.cnblogs.com/756623607-zhang/p/6656022.html
數據庫路由中間件MyCat - 使用篇(5)
配置MyCat
4. 配置schema.xml
schema.xml里面管理着MyCat的邏輯庫、表,每張表使用的分片規則、分布在哪個DataNode以及DataSource上。
之前的例子:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://org.opencloudb/"> <!--schema就是邏輯庫,相當於MySQL實例的數據庫,一個MySQL實例可以有多個數據庫,同樣的一個MyCat實例也可以有多個schema--> <!-- checkSQLschema就是打開SQL語句檢查,把帶schema名字的查詢改寫成不帶的,一般查詢最好不要帶schema名字 --> <!--sqlMaxLimit每條執行的SQL語句,如果沒有加上limit語句,MyCat也會自動的加上所對應的值--> <schema name="schema1" checkSQLschema="false" sqlMaxLimit="10000" dataNode="test4"> <!-- 運單表,分片列在rule.xml配置,這里正好就是主鍵id,所以分片規則是主鍵id對3取模--> <table name="orders" primaryKey="id" dataNode="test$1-3" rule="mod-long-orders"> <!-- 運單子母件表,運單表的子表,order_id與orders的id列對應 --> <childTable name="orders_cargo" joinKey="order_id" parentKey="id"> </childTable> <!-- 客戶運單關系表,運單表的子表,order_id與orders的id列對應 --> <childTable name="customer_order_rel" joinKey="order_id" parentKey="id"> </childTable> <!-- 快遞員運單關系表,運單表的子表,order_id與orders的id列對應 --> <childTable name="courier_order_rel" joinKey="order_id" parentKey="id"> </childTable> </table> <!-- 運單狀態信息表,公共表,放在和運單表同樣的分片上 --> <table name="order_status_interception" primaryKey="id" type="global" dataNode="test$1-3"> </table> <!-- 快遞員表,非分片表 --> <table name="courier" primaryKey="id" dataNode="test4"> </table> <!-- 客戶表,對主鍵id對2取模 --> <table name="customer" primaryKey="id" dataNode="test$5-6" rule="mod-long-customer"> </table> </schema> <!-- 規定dataNode,就是分片的位置--> <dataNode name="test1" dataHost="test" database="db1" /> <dataNode name="test2" dataHost="test" database="db2" /> <dataNode name="test3" dataHost="test" database="db3" /> <dataNode name="test4" dataHost="test" database="db4" /> <dataNode name="test5" dataHost="test" database="db5" /> <dataNode name="test6" dataHost="test" database="db6" /> <!-- 規定每個分片host的讀寫服務器以及登錄用戶名密碼,還有心跳語句--> <dataHost name="test" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"> <heartbeat>select 1 from dual</heartbeat> <writeHost host="test" url="10.202.4.181:3306" user="test" password="test"> <readHost host="slave" url="10.202.4.181:3307" user="root" password="sf123456"/> </writeHost> </dataHost> </mycat:schema>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
邏輯庫配置schema標簽:
<!--schema就是邏輯庫,相當於MySQL實例的數據庫,一個MySQL實例可以有多個數據庫,同樣的一個MyCat實例也可以有多個schema--> <!-- checkSQLschema就是打開SQL語句檢查,把帶schema名字的查詢改寫成不帶的,一般查詢最好不要帶schema名字 --> <!--sqlMaxLimit每條執行的SQL語句,如果沒有加上limit語句,MyCat也會自動的加上所對應的值--> <schema name="schema1" checkSQLschema="false" sqlMaxLimit="10000" dataNode="test4"> </schema>
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
其中,這里配置的dataNode屬性,是指這個邏輯庫中邏輯表的默認分片節點是test4,如果邏輯表自己配置了分片節點,那么這個屬性對那個邏輯表無效。
sqlMaxLimit防止過多的輸出,如果sql語句中顯式的指定了limit大小,那么這個屬性就不會生效。而且,如果對於非分片表執行sql語句,這個屬性也不會生效。
邏輯表配置table標簽:
<!-- 運單表,分片列在rule.xml配置,這里正好就是主鍵id,所以分片規則是主鍵id對3取模--> <table name="orders" primaryKey="id" dataNode="test$1-3" rule="mod-long-orders"> <!-- 運單子母件表,運單表的子表,order_id與orders的id列對應 --> <childTable name="orders_cargo" joinKey="order_id" parentKey="id"> </childTable> <!-- 客戶運單關系表,運單表的子表,order_id與orders的id列對應 --> <childTable name="customer_order_rel" joinKey="order_id" parentKey="id"> </childTable> <!-- 快遞員運單關系表,運單表的子表,order_id與orders的id列對應 --> <childTable name="courier_order_rel" joinKey="order_id" parentKey="id"> </childTable> </table> <!-- 運單狀態信息表,公共表,放在和運單表同樣的分片上 --> <table name="order_status_interception" primaryKey="id" type="global" dataNode="test$1-3"> </table> <!-- 快遞員表,非分片表 --> <table name="courier" primaryKey="id" dataNode="test4"> </table> <!-- 客戶表,對主鍵id對2取模 --> <table name="customer" primaryKey="id" dataNode="test$5-6" rule="mod-long-customer"> </table>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- name屬性定義邏輯表的表名,這個名字就如同我在數據庫中執行create table命令指定的名字一樣,同個schema標簽中定義的名字必須唯一。
- dataNode屬性:定義這個邏輯表所屬的dataNode, 該屬性的值需要和dataNode標簽中name屬性的值相互對應。如果需要定義的dn過多可以使用上面配置的的方法減少配置
- rule屬性:該屬性用於指定邏輯表要使用的規則名字,規則名字在rule.xml中定義,必須與tableRule標簽中name屬性屬性值一一對應。
- ruleRequired屬性:該屬性用於指定表是否綁定分片規則,如果配置為true,但沒有配置具體rule的話 ,程序會報錯。
- primaryKey屬性:該邏輯表對應真實表的主鍵,例如:分片的規則是使用非主鍵進行分片的,那么在使用主鍵查詢的時候,就會發送查詢語句到所有配置的DN上;如果使用該屬性配置真實表的主鍵,那么MyCat會緩存主鍵與具體DN的信息,那么再次使用非主鍵進行查詢的時候就不會進行廣播式的查詢,就會直接發送語句給具體的DN,但是盡管配置該屬性,如果緩存並沒有命中的話,還是會發送語句給具體的DN,來獲得數據。
- type屬性:該屬性定義了邏輯表的類型,目前邏輯表只有“全局表”和”普通表”兩種類型。全局表:global。普通表:不指定該值為globla的所有表。
- autoIncrement屬性:自增id相關,不推薦使用
- needAddLimit屬性:指定表是否需要自動的在每個語句后面加上limit限制。由於使用了分庫分表,數據量有時會特別巨大。這時候執行查詢語句,如果恰巧又忘記了加上數量限制的話。那么查詢所有的數據出來,也夠等上一小會兒的。所以,mycat就自動的為我們加上LIMIT 100。當然,如果語句中有limit,就不會在次添加了。這個屬性默認為true,你也可以設置成false`禁用掉默認行為。
分片表子表配置 childTable標簽:
<table name="orders" primaryKey="id" dataNode="test$1-3" rule="mod-long-orders"> <!-- 運單子母件表,運單表的子表,order_id與orders的id列對應 --> <childTable name="orders_cargo" joinKey="order_id" parentKey="id"> </childTable> <!-- 客戶運單關系表,運單表的子表,order_id與orders的id列對應 --> <childTable name="customer_order_rel" joinKey="order_id" parentKey="id"> </childTable> <!-- 快遞員運單關系表,運單表的子表,order_id與orders的id列對應 --> <childTable name="courier_order_rel" joinKey="order_id" parentKey="id"> </childTable> </table>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- name屬性
- joinKey屬性:插入子表的時候會使用這個列的值查找父表存儲的數據節點。
- parentKey屬性:屬性指定的值一般為與父表建立關聯關系的列名。程序首先獲取joinkey的值,再通過parentKey屬性指定的列名產生查詢語句,通過執行該語句得到父表存儲在哪個分片上。從而確定子表存儲的位置。
- primaryKey屬性:同table標簽所描述的。
- needAddLimit屬性:同table標簽所描述的。
分片節點dataNode標簽配置:
<!-- 規定dataNode,就是分片的位置--> <dataNode name="test1" dataHost="test" database="db1" /> <dataNode name="test2" dataHost="test" database="db2" /> <dataNode name="test3" dataHost="test" database="db3" /> <dataNode name="test4" dataHost="test" database="db4" /> <dataNode name="test5" dataHost="test" database="db5" /> <dataNode name="test6" dataHost="test" database="db6" />
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- name屬性
- dataHost屬性:該屬性用於定義該分片屬於哪個數據庫實例的,屬性值是引用dataHost標簽上定義的name屬性
- database屬性:該屬性用於定義該分片屬性哪個具體數據庫實例上的具體庫,因為這里使用兩個緯度來定義分片,就是:實例+具體的庫。因為每個庫上建立的表和表結構是一樣的。所以這樣做就可以輕松的對表進行水平拆分。
分片主機dataHost標簽配置:
<!-- 規定每個分片host的讀寫服務器以及登錄用戶名密碼,還有心跳語句--> <dataHost name="test" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"> <heartbeat>select 1 from dual</heartbeat> <writeHost host="test" url="10.202.4.181:3306" user="test" password="test"> <readHost host="slave" url="10.202.4.181:3307" user="root" password="sf123456"/> </writeHost> </dataHost>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
dataHost標簽:該標簽在mycat邏輯庫中也是作為最底層的標簽存在,直接定義了具體的數據庫實例、讀寫分離配置和心跳語句。
- name屬性
- maxCon屬性:指定每個讀寫實例連接池的最大連接。也就是說,標簽內嵌套的writeHost、readHost標簽都會使用這個屬性的值來實例化出連接池的最大連接數。
- minCon屬性:指定每個讀寫實例連接池的最小連接,初始化連接池的大小。
- balance屬性:
- balance=“0”, 所有讀操作都發送到當前可用的writeHost上。
- balance=“1”,所有讀操作都隨機的發送到readHost。
- balance=“2”,所有讀操作都隨機的在writeHost、readhost上分發。 - writeType屬性
- writeType=“0”, 所有寫操作都發送到可用的writeHost上。
- writeType=“1”,所有寫操作都隨機的發送到readHost。
- writeType=“2”,所有寫操作都隨機的在writeHost、readhost分上發。 - dbType屬性:指定后端連接的數據庫類型,目前支持二進制的mysql協議,還有其他使用JDBC連接的數據庫。例如:mongodb、oracle、spark等。
- dbDriver屬性:指定連接后端數據庫使用的Driver,目前可選的值有native和JDBC。使用native的話,因為這個值執行的是二進制的mysql協議,所以可以使用mysql和maridb。其他類型的數據庫則需要使用JDBC驅動來支持。
- switchType屬性:
-1 表示不自動切換
1 默認值,自動切換
2 基於 MySQL 主從同步狀態決定是否切換,心跳語句必須為show slave status
3 基於 MySQL galary cluster 的切換機制(適合集群)心跳語句必須為show status like ‘wsrep%’ - slaveThreshold:主從同步狀態決定是否切換,延遲超過這個就不切換
- heartbeat標簽:這個標簽內指明用於和后端數據庫進行心跳檢查的語句。例如,MYSQL可以使用select user(),Oracle可以使用select 1 from dual等。
- writeHost標簽、readHost標簽:這兩個標簽都指定后端數據庫的相關配置給mycat,用於實例化后端連接池。唯一不同的是,writeHost指定寫實例、readHost指定讀實例,組着這些讀寫實例來滿足系統的要求。在一個dataHost內可以定義多個writeHost和readHost。但是,如果writeHost指定的后端數據庫宕機,那么這個writeHost綁定的所有readHost都將不可用。另一方面,由於這個writeHost宕機系統會自動的檢測到,並切換到備用的writeHost上去。
- host屬性:用於標識不同實例
- url屬性:后端實例連接地址,如果是使用native的dbDriver,則一般為address:port這種形式。用JDBC或其他的dbDriver,則需要特殊指定。當使用JDBC時則可以這么寫:jdbc:mysql://localhost:3306/。
- user屬性:后端存儲實例需要的用戶名字
- password屬性:后端存儲實例需要的密碼
5. 啟動MyCat
以上,MyCat基本配置已經配置好。下面則啟動,進入mycat的bin目錄,啟動MyCat:
./mycat start
查看啟動狀態:
./mycat status
停止:
./mycat stop
重啟(改變上面的xml配置不用重啟,管理端可以重新載入,以后會講):
./mycat restart
查看logs/下的wrapper.log和mycat.log可以查看運行時問題和異常。
訪問MyCat(這里為127.0.0.1:8066),可以看到: