windows環境下Mycat的安裝、配置和測試使用

Mycat是什麼

詳見(官網

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

Mycat作用

(1). 集中管理多個數據庫連接(分佈式解決方案)
(2). 配置讀寫分離
(3). 配置數據庫分片(分表、分庫)等 (本文視角)

安裝配置

1. 準備

環境:jdk1.8、mysql5.6、mycat1.6.7(官網
測試工具:Navicat12

2. 目錄結構

在這裏插入圖片描述
圖中分別對應執行、配置、日誌等文件目錄

3. 配置

主要配置server.xml、schema.xml、rule.xml等文件,下面每個配置的內容均來自本地測試分表分庫配置結果。內容已經包含詳細介紹和說明。
server.xml:啓動服務相關配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
	- you may not use this file except in compliance with the License. - You 
	may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
	- - Unless required by applicable law or agreed to in writing, software - 
	distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
	License for the specific language governing permissions and - limitations 
	under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
	<system>
	<property name="nonePasswordLogin">0</property> <!-- 0爲需要密碼登陸、1爲不需要密碼登陸 ,默認爲0,設置爲1則需要指定默認賬戶-->
	<property name="ignoreUnknownCommand">0</property><!-- 0遇上沒有實現的報文(Unknown command:),就會報錯、1爲忽略該報文,返回ok報文。
	在某些mysql客戶端存在客戶端已經登錄的時候還會繼續發送登錄報文,mycat會報錯,該設置可以繞過這個錯誤-->
	<property name="useHandshakeV10">1</property>
    <property name="removeGraveAccent">1</property>
	<property name="useSqlStat">0</property>  <!-- 1爲開啓實時統計、0爲關閉 -->
	<property name="useGlobleTableCheck">0</property>  <!-- 1爲開啓全加班一致性檢測、0爲關閉 -->
		<property name="sqlExecuteTimeout">300</property>  <!-- SQL 執行超時 單位:秒-->
		<property name="sequnceHandlerType">1</property>
		<!--<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
		INSERT INTO `travelrecord` (`id`,user_id) VALUES ('next value for MYCATSEQ_GLOBAL',"xxx");
		-->
		<!--必須帶有MYCATSEQ_或者 mycatseq_進入序列匹配流程 注意MYCATSEQ_有空格的情況-->
		<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
	<property name="subqueryRelationshipCheck">false</property> <!-- 子查詢中存在關聯查詢的情況下,檢查關聯字段中是否有分片字段 .默認 false -->
	<property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property>
      <!--  <property name="useCompression">1</property>--> <!--1爲開啓mysql壓縮協議-->
        <!--  <property name="fakeMySQLVersion">5.6.20</property>--> <!--設置模擬的MySQL版本號-->
	<!-- <property name="processorBufferChunk">40960</property> -->
	<!-- 
	<property name="processors">1</property> 
	<property name="processorExecutor">32</property> 
	 -->
        <!--默認爲type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
		<property name="processorBufferPoolType">0</property>
		<!--默認是65535 64K 用於sql解析時最大文本長度 -->
		<!--<property name="maxStringLiteralLength">65535</property>-->
		<!--<property name="sequnceHandlerType">0</property>-->
		<!--<property name="backSocketNoDelay">1</property>-->
		<!--<property name="frontSocketNoDelay">1</property>-->
		<!--<property name="processorExecutor">16</property>-->
		<!--
			<property name="serverPort">8066</property> <property name="managerPort">9066</property> 
			<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
			<property name="dataNodeIdleCheckPeriod">300000</property> 5 * 60 * 1000L; //連接空閒檢查
			<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
		<!--分佈式事務開關,0爲不過濾分佈式事務,1爲過濾分佈式事務(如果分佈式事務內只涉及全局表,則不過濾),2爲不過濾分佈式事務,但是記錄分佈式事務日誌-->
		<property name="handleDistributedTransactions">0</property>
		
			<!--
			off heap for merge/order/group/limit      1開啓   0關閉
		-->
		<property name="useOffHeapForMerge">0</property>

		<!--
			單位爲m
		-->
        <property name="memoryPageSize">64k</property>

		<!--
			單位爲k
		-->
		<property name="spillsFileBufferSize">1k</property>

		<property name="useStreamOutput">0</property>

		<!--
			單位爲m
		-->
		<property name="systemReserveMemorySize">384m</property>


		<!--是否採用zookeeper協調切換  -->
		<property name="useZKSwitch">false</property>

		<!-- XA Recovery Log日誌路徑 -->
		<!--<property name="XARecoveryLogBaseDir">./</property>-->

		<!-- XA Recovery Log日誌名稱 -->
		<!--<property name="XARecoveryLogBaseName">tmlog</property>-->
		<!--如果爲 true的話 嚴格遵守隔離級別,不會在僅僅只有select語句的時候在事務中切換連接-->
		<property name="strictTxIsolation">false</property>
		
		<property name="useZKSwitch">true</property>
		<!--如果爲0的話,涉及多個DataNode的catlet任務不會跨線程執行-->
		<property name="parallExecute">0</property>
	</system>
	
	<!-- 全局SQL防火牆設置 -->
	<!--白名單可以使用通配符%或着*-->
	<!--例如<host host="127.0.0.*" user="root"/>-->
	<!--例如<host host="127.0.*" user="root"/>-->
	<!--例如<host host="127.*" user="root"/>-->
	<!--例如<host host="1*7.*" user="root"/>-->
	<!--這些配置情況下對於127.0.0.1都能以root賬戶登錄-->
	<!--
	<firewall>
	   <whitehost>
	      <host host="1*7.0.0.*" user="root"/>
	   </whitehost>
       <blacklist check="false">
       </blacklist>
	</firewall>
	-->

	<user name="root" defaultAccount="true">
		<property name="password">root</property>
		<property name="schemas">TESTDB</property>
		<property name="defaultSchema">TESTDB</property>
		<!--No MyCAT Database selected 錯誤前會嘗試使用該schema作爲schema,不設置則爲null,報錯 -->
		
		<!-- 表級 DML 權限設置 -->
		<!-- 		
		<privileges check="false">
			<schema name="TESTDB" dml="0110" >
				<table name="tb01" dml="0000"></table>
				<table name="tb02" dml="1111"></table>
			</schema>
		</privileges>		
		 -->
	</user>
<!--
	<user name="root">
		<property name="password">root</property>
		<property name="schemas">TESTDB</property>
		<property name="readOnly">true</property>
		<property name="defaultSchema">TESTDB</property>
	</user>-->

</mycat:server>

這裏配置的用戶user標籤名稱不能相同,一般只配置一個

schema.xml:庫、表相關配置

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

	<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
		<!-- auto sharding by id (long) -->
		<!--splitTableNames 啓用<table name 屬性使用逗號分割配置多個表,即多個表使用這個配置-->
		<!-- <table name="travelrecord,address" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" splitTableNames ="true"/> -->
		<!-- <table name="oc_call" primaryKey="ID" dataNode="dn1$0-743" rule="latest-month-calldate"
			/> -->
		<!--                   邏輯表 可以多個                  -->	
        <table name="address" rule="auto-sharding-long"  primaryKey="ID"  dataNode="dn1,dn2,dn3" /> 
		<!--name需要與數據庫表對應 primaryKey主鍵ID rule分片規則 數據分佈在dn1、dn2、dn3三個數據節點dataNode -->
		<table name="company" primaryKey="ID" type="global" dataNode="dn1" />
		<!--沒有分片的表 默認是普通表 type=global表 會將所有dataNode的數據拷貝一份到該邏輯表中-->
	</schema>
	<!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
		/> -->
	<dataNode name="dn1" dataHost="localhost1" database="db1" />
	<dataNode name="dn2" dataHost="localhost1" database="db2" />
	<dataNode name="dn3" dataHost="localhost1" database="db3" />
	<!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" />
	 <dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" />
	<dataNode	name="jdbc_dn2" dataHost="jdbchost" database="db2" />
	<dataNode name="jdbc_dn3" 	dataHost="jdbchost" database="db3" /> -->
	<dataHost name="localhost1" 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="xxx.xxx.xxx.xxx:3306" user="root"
				   password="root">
		</writeHost>
		<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
	</dataHost>
	<!--
		<dataHost name="sequoiadb1" maxCon="1000" minCon="1" balance="0" dbType="sequoiadb" dbDriver="jdbc">
		<heartbeat> 		</heartbeat>
		 <writeHost host="hostM1" url="sequoiadb://1426587161.dbaas.sequoialab.net:11920/SAMPLE" user="jifeng" 	password="jifeng"></writeHost>
		 </dataHost>

	  <dataHost name="oracle1" maxCon="1000" minCon="1" balance="0" writeType="0" 	dbType="oracle" dbDriver="jdbc"> <heartbeat>select 1 from dual</heartbeat>
		<connectionInitSql>alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'</connectionInitSql>
		<writeHost host="hostM1" url="jdbc:oracle:thin:@127.0.0.1:1521:nange" user="base" 	password="123456" > </writeHost> </dataHost>

		<dataHost name="jdbchost" maxCon="1000" 	minCon="1" balance="0" writeType="0" dbType="mongodb" dbDriver="jdbc">
		<heartbeat>select 	user()</heartbeat>
		<writeHost host="hostM" url="mongodb://192.168.0.99/test" user="admin" password="123456" ></writeHost> </dataHost>

		<dataHost name="sparksql" maxCon="1000" minCon="1" balance="0" dbType="spark" dbDriver="jdbc">
		<heartbeat> </heartbeat>
		 <writeHost host="hostM1" url="jdbc:hive2://feng01:10000" user="jifeng" 	password="jifeng"></writeHost> </dataHost> -->

	<!-- <dataHost name="jdbchost" maxCon="1000" minCon="10" balance="0" dbType="mysql"
		dbDriver="jdbc"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1"
		url="jdbc:mysql://localhost:3306" user="root" password="123456"> </writeHost>
		</dataHost> -->
</mycat:schema>

rule.xml: 規則相關配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License"); 
	- you may not use this file except in compliance with the License. - You 
	may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 
	- - Unless required by applicable law or agreed to in writing, software - 
	distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT 
	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the 
	License for the specific language governing permissions and - limitations 
	under the License. -->
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
	<tableRule name="rule1">
		<rule>
			<columns>id</columns>
			<algorithm>func1</algorithm>
		</rule>
	</tableRule>

	<tableRule name="sharding-by-date">
		<rule>
			<columns>createTime</columns>
			<algorithm>partbyday</algorithm>
		</rule>
	</tableRule>

	<tableRule name="rule2">
		<rule>
			<columns>user_id</columns>
			<algorithm>func1</algorithm>
		</rule>
	</tableRule>

	<tableRule name="sharding-by-intfile">
		<rule>
			<columns>sharding_id</columns>
			<algorithm>hash-int</algorithm>
		</rule>
	</tableRule>
	<tableRule name="auto-sharding-long">
		<rule>
			<columns>id</columns>
			<algorithm>rang-long</algorithm>
		</rule>
	</tableRule>
	<tableRule name="mod-long">
		<rule>
			<columns>id</columns>
			<algorithm>mod-long</algorithm>
		</rule>
	</tableRule>
	<tableRule name="sharding-by-murmur">
		<rule>
			<columns>id</columns>
			<algorithm>murmur</algorithm>
		</rule>
	</tableRule>
	<tableRule name="crc32slot">
		<rule>
			<columns>id</columns>
			<algorithm>crc32slot</algorithm>
		</rule>
	</tableRule>
	<tableRule name="sharding-by-month">
		<rule>
			<columns>create_time</columns>
			<algorithm>partbymonth</algorithm>
		</rule>
	</tableRule>
	<tableRule name="latest-month-calldate">
		<rule>
			<columns>calldate</columns>
			<algorithm>latestMonth</algorithm>
		</rule>
	</tableRule>

	<tableRule name="auto-sharding-rang-mod">
		<rule>
			<columns>id</columns>
			<algorithm>rang-mod</algorithm>
		</rule>
	</tableRule>

	<tableRule name="jch">
		<rule>
			<columns>id</columns>
			<algorithm>jump-consistent-hash</algorithm>
		</rule>
	</tableRule>

	<function name="murmur"
			  class="io.mycat.route.function.PartitionByMurmurHash">
		<property name="seed">0</property><!-- 默認是0 -->
		<property name="count">2</property><!-- 要分片的數據庫節點數量,必須指定,否則沒法分片 -->
		<property name="virtualBucketTimes">160</property><!-- 一個實際的數據庫節點被映射爲這麼多虛擬節點,默認是160倍,也就是虛擬節點數是物理節點數的160倍 -->
		<!-- <property name="weightMapFile">weightMapFile</property> 節點的權重,沒有指定權重的節點默認是1。以properties文件的格式填寫,以從0開始到count-1的整數值也就是節點索引爲key,以節點權重值爲值。所有權重值必須是正整數,否則以1代替 -->
		<!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property>
			用於測試時觀察各物理節點與虛擬節點的分佈情況,如果指定了這個屬性,會把虛擬節點的murmur hash值與物理節點的映射按行輸出到這個文件,沒有默認值,如果不指定,就不會輸出任何東西 -->
	</function>

	<function name="crc32slot"
			  class="io.mycat.route.function.PartitionByCRC32PreSlot">
		<property name="count">2</property><!-- 要分片的數據庫節點數量,必須指定,否則沒法分片 -->
	</function>
	<function name="hash-int"
			  class="io.mycat.route.function.PartitionByFileMap">
		<property name="mapFile">partition-hash-int.txt</property>
	</function>
	<function name="rang-long"
			  class="io.mycat.route.function.AutoPartitionByLong">
		<property name="mapFile">autopartition-long.txt</property>
	</function>
	<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<property name="count">3</property>
	</function>

	<function name="func1" class="io.mycat.route.function.PartitionByLong">
		<property name="partitionCount">8</property>
		<property name="partitionLength">128</property>
	</function>
	<function name="latestMonth"
			  class="io.mycat.route.function.LatestMonthPartion">
		<property name="splitOneDay">24</property>
	</function>
	<function name="partbymonth"
			  class="io.mycat.route.function.PartitionByMonth">
		<property name="dateFormat">yyyy-MM-dd</property>
		<property name="sBeginDate">2015-01-01</property>
	</function>


	<function name="partbyday"
			  class="io.mycat.route.function.PartitionByDate">
		<property name="dateFormat">yyyy-MM-dd</property>
		<property name="sNaturalDay">0</property>
		<property name="sBeginDate">2014-01-01</property>
		<property name="sEndDate">2014-01-31</property>
		<property name="sPartionDay">10</property>
	</function>

	<function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
		<property name="mapFile">partition-range-mod.txt</property>
	</function>

	<function name="jump-consistent-hash" class="io.mycat.route.function.PartitionByJumpConsistentHash">
		<property name="totalBuckets">3</property>
	</function>
</mycat:rule>

這裏的規則對應具體規則文件在conf下,如本例查找使用規則文件過程:
先在schema.xml中找到 :

<!--name需要與數據庫表對應 primaryKey主鍵ID rule分片規則 數據分佈在dn1、dn2、dn3三個數據節點dataNode -->
<table name="address" rule="auto-sharding-long"  primaryKey="ID"  dataNode="dn1,dn2,dn3" /> 
<!--沒有分片的表 默認是普通表 type=global表 會將所有dataNode的數據拷貝一份到該邏輯表中-->
<table name="company" primaryKey="ID" type="global" dataNode="dn1" />

可以發現,表address的規則,auto-sharding-long,通過這個規則去rule.xml查詢,結果如下:

<tableRule name="auto-sharding-long">
	<rule>
		<columns>id</columns>
		<algorithm>rang-long</algorithm>
	</rule>
</tableRule>

再通過rang-long找到關聯的函數,如下:

<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
	<property name="mapFile">autopartition-long.txt</property>
</function>

再去conf/目錄下查詢此文件,內容如下:

# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2

注意:k= 1000 M=1000,上面文件內容默認是500萬數據一個表

4.使用測試

打開navicat,連接mycat,server.xml的user標籤配置的用戶名和密碼,還有數據庫,我的截圖如下:
xuyao在這裏插入圖片描述
需要的兩個數據庫,我是在阿里雲上部署的兩個mysq實例,可自己本地部署
創建的庫db1、db2、db3
創建表格腳本:(記得每個庫都得創建schma.xml中配置的表格)


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for address
-- ----------------------------
DROP TABLE IF EXISTS `address`;
CREATE TABLE `address`  (
  `id` int(11) NOT NULL,
  `addressname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Table structure for company
-- ----------------------------
DROP TABLE IF EXISTS `company`;
CREATE TABLE `company`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `companyname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `addressid` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 235 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Table structure for test
-- ----------------------------
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test`  (
  `id` bigint(20) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Table structure for travelrecord
-- ----------------------------
DROP TABLE IF EXISTS `travelrecord`;
CREATE TABLE `travelrecord`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `traveldate` date NULL DEFAULT NULL,
  `fee` decimal(10, 0) NULL DEFAULT NULL,
  `days` int(11) NULL DEFAULT NULL,
  `blob` longblob NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Table structure for travelrecord2
-- ----------------------------
DROP TABLE IF EXISTS `travelrecord2`;
CREATE TABLE `travelrecord2`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `traveldate` date NULL DEFAULT NULL,
  `fee` decimal(10, 0) NULL DEFAULT NULL,
  `days` int(11) NULL DEFAULT NULL,
  `blob` longblob NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Table structure for travelrecord3
-- ----------------------------
DROP TABLE IF EXISTS `travelrecord3`;
CREATE TABLE `travelrecord3`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `traveldate` date NULL DEFAULT NULL,
  `fee` decimal(10, 0) NULL DEFAULT NULL,
  `days` int(11) NULL DEFAULT NULL,
  `blob` longblob NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

測試數據

INSERT INTO address(id, addressname) VALUES(5000000,1100) #對應db1的address
INSERT INTO address(id, addressname) VALUES(5000001,1100) #對應db2的address
INSERT INTO address(id, addressname) VALUES(10000001,1100) #對應db3的address
INSERT INTO address(id, addressname) VALUES(15000001,1100) #無對應

只是測試了分庫分表,還可以配置讀寫分離,多數據源集羣管理等

最新的mycat2,配置發生了變化,均在mycat.yml中配置server、schma、rule。並有sample文件,有對應的配置demo可參考。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章