mycat分库分表和读写分离

发布时间 2023-06-21 15:01:22作者: 数据库小白(专注)

1. mycat分库分表和读写分离

1.1. 分库分表实现

1.1.1. Mycat安装与配置详解

1.1.1.1. 下载地址

[mycat](https://github.com/InstallingB/Mycat2)
[mycat2](http://dl.mycat.org.cn/)

以1.6.7.1版本为例:
根据不同这里下载不同的版本(这里没有显示全,补过可以通过把鼠标移上去看左下角显示的链接信息)
因为我要下linux版本的。所以我下载第一个Mycat-server-1.6.7.1-release-20190213150257-lin的

1.1.1.2. 解压安装包

tar -xvf Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz

可以看到解压出来的内容都放到mycat文件夹中了。
目录说明:

  • bin:命令文件
  • catlet:空的,扩展
  • conf:配置文件(server.xml,schema.xml,rule.xml等)
  • lib:依赖的jar包
    在mycat根目录创建logs文件夹,会把日志自动记录到这里。
    如果启动报错可以到此目录查看日志
    注意防火墙策略,并且添加/etc/hosts 中的主机名和IP的对应。

1.1.2. 修改mycat内存配置

我的linux虚拟机配置的内存大小是1GB,大家需要根据自己的实际情况进行配置

[root@centos212 local]# vi mycat/conf/wrapper.conf

wrapper.java.additional.10=-Xmx4G    (大约在36行)
wrapper.java.additional.11=-Xms1G
改成
wrapper.java.additional.10=-Xmx1G
wrapper.java.additional.11=-Xms256M

添加环境变量
将MyCat配置到环境变量中

MYCAT_HOME=/usr/local/mycat
PATH=$MYCAT_HOME/bin:$PATH

1.1.3. 配置实例

1.1.4. 环境准备

两台虚拟机

  • Host1 : 192.168.12.66
  • Host2 : 192.168.12.88
  • MySQL 5.7
  • Mycat 1.6
    aHR0cDovL3d3Mi5zaW5haW1nLmNuL2xhcmdlLzAwNnROYzc5Z3kxZzV4YzJzMHBhaGozMHp2MHE0ZGsyLmpwZw

1.1.4.1. 分库分表规则

mycat定义两个逻辑库,分别为db_user、db_store
表db_user按照模分成2个片,分别落在host1、host2上
表db_store为主从复制模式,分别落在host1、host2上

1.1.4.2. 创建数据库和表结构

分别在HOST1、HOST2执行db_user.sql

CREATE DATABASE db_user DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

use db_user;

-- ----------------------------
-- Table structure for data_dictionary
-- ----------------------------
DROP TABLE IF EXISTS `data_dictionary`;
CREATE TABLE `data_dictionary` (
  `dataDictionaryID` int(11) NOT NULL COMMENT '数据字典ID',
  `displayName` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '显示名称',
  `value` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '数据字典取值',
  `createTime` datetime DEFAULT NULL COMMENT '创建时间',
  `lastUpdate` datetime DEFAULT NULL COMMENT '最后更新时间',
  PRIMARY KEY (`dataDictionaryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Table structure for user_address
-- ----------------------------
DROP TABLE IF EXISTS `user_address`;

CREATE TABLE `user_address` (
  `addressID` int(11) NOT NULL COMMENT '地址ID',
  `receiver` varchar(16) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人',
  `addressDetail` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '地址详细',
  `userID` int(11) NOT NULL COMMENT '用户ID',
  `createTime` datetime DEFAULT NULL COMMENT '创建时间',
  `lastUpdate` datetime DEFAULT NULL COMMENT '最后更新时间',
  PRIMARY KEY (`addressID`,`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `userID` int(11) NOT NULL COMMENT '用户ID',
  `username` varchar(16) COLLATE utf8_bin DEFAULT NULL COMMENT '用户名',
  `phoneNum` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '手机号码',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `ddID` int(11) DEFAULT NULL COMMENT '所属会员类型',
  `createTime` datetime DEFAULT NULL COMMENT '注册时间',
  `lastUpdate` datetime DEFAULT NULL COMMENT '最后更新时间',
  PRIMARY KEY (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

只需要在HOST1(192.168.12.66)上执行db_store.sql,HOST2主从复制会自动同步数据

CREATE DATABASE  db_store DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

use db_store;
-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
  `employeeID` int(11) NOT NULL,
  `userName` varchar(16) COLLATE utf8_bin DEFAULT NULL,
  `phoneNum` varchar(32) COLLATE utf8_bin DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `createTime` datetime DEFAULT NULL,
  `lastUpdate` datetime DEFAULT NULL,
  PRIMARY KEY (`employeeID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Table structure for store
-- ----------------------------
DROP TABLE IF EXISTS `store`;
CREATE TABLE `store` (
  `storeID` int(11) NOT NULL,
  `storeName` varchar(32) COLLATE utf8_bin DEFAULT NULL,
  `storeAddress` varchar(256) COLLATE utf8_bin DEFAULT NULL,
  `createTime` datetime DEFAULT NULL,
  `lastUpdate` datetime DEFAULT NULL,
  PRIMARY KEY (`storeID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

执行完毕可以看到两个数据库下都对应生成了表。

1.1.4.3. 配置conf文件

两台host主机Mycat的conf目录下配置三个配置文件
schema.xml

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

	<schema name="db_store" checkSQLschema="false" sqlMaxLimit="100">
		<table name="store" dataNode="db_store_dataNode" primaryKey="storeID"/>
		<table name="employee" dataNode="db_store_dataNode" primaryKey="employeeID"/>
	</schema>
	
	
	<schema name="db_user" checkSQLschema="false" sqlMaxLimit="100">
		<table name="data_dictionary" type="global" dataNode="db_user_dataNode1,db_user_dataNode2" primaryKey="dataDictionaryID"/>
		<table name="users" dataNode="db_user_dataNode$1-2"  rule="mod-userID-long" primaryKey="userID">
			<childTable name="user_address"  joinKey="userID" parentKey="userID" primaryKey="addressID"/>
		</table>
	</schema>
	
	
	<!-- 节点配置 -->
	<!-- db_store -->
	<dataNode name="db_store_dataNode" dataHost="db_storeHOST" database="db_store" />
	
	<!-- db_user -->
	<dataNode name="db_user_dataNode1" dataHost="db_userHOST1" database="db_user" />
	<dataNode name="db_user_dataNode2" dataHost="db_userHOST2" database="db_user" />
	
	
	
	
	<!-- 节点主机配置 -->
	<!-- 配置db_store的节点主机 -->
	<dataHost name="db_storeHOST" maxCon="1000" minCon="10" balance="1"
			  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.12.66:3306" user="root"  password="123456">
			<!-- can have multi read hosts -->
			<readHost host="hostS1" url="192.168.12.88:3306" user="root" password="123456" />
		
		
		</writeHost>
		
	</dataHost>
	
	
	<!-- 配置db_user的节点主机 -->
	<dataHost name="db_userHOST1" maxCon="1000" minCon="10" balance="0"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<writeHost host="userHost1" url="192.168.12.66:3306" user="root"  password="123456">
		</writeHost>
	</dataHost>
	
	<dataHost name="db_userHOST2" 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="userHost2" url="192.168.12.88:3306" user="root"  password="123456">
		</writeHost>
	</dataHost>
	
</mycat:schema>

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="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
	<property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->

		<property name="sequnceHandlerType">2</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-->
		<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="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">1</property>

		<!--
			单位为m
		-->
		<property name="memoryPageSize">1m</property>

		<!--
			单位为k
		-->
		<property name="spillsFileBufferSize">1k</property>

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

		<!--
			单位为m
		-->
		<property name="systemReserveMemorySize">384m</property>


		<!--是否采用zookeeper协调切换  -->
		<property name="useZKSwitch">true</property>


	</system>
	
	<!-- 全局SQL防火墙设置 -->
	<!-- 
	<firewall> 
	   <whitehost>
	      <host host="127.0.0.1" user="mycat"/>
	      <host host="127.0.0.2" user="mycat"/>
	   </whitehost>
       <blacklist check="false">
       </blacklist>
	</firewall>
	-->
	
	<user name="root">
		<property name="password">123456</property>
		<property name="schemas">db_store,db_user</property>
		
		<!-- 表级 DML 权限设置 -->
		<!-- 		
		<privileges check="false">
			<schema name="db_user" dml="0110" >
				<table name="users" dml="1111"></table>  IUSD
				<table name="useraddres" dml="1110"></table>
			</schema>
		</privileges>		
		 -->
	</user>

</mycat:server>

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="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="mod-userID-long">
		<rule>
			<columns>userID</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="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<property name="count">2</property>
	</function>

	<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="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="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>

1.1.4.4. 重启mycat

[root@localhost bin]# pwd
/software/mycat/bin
[root@localhost bin]# ./mycat restart
Stopping Mycat-server...
Mycat-server was not running.
Starting Mycat-server...
[root@localhost bin]# ./mycat status
Mycat-server is running (8228).

注意mycat是java编写的,因此需要安装jdk,此处省略

1.1.4.5. 连接mycat

linux 控制台 mysql -uroot -padmin -P8066 -h192.168.12.66
查看逻辑库show database;
只能看到逻辑库 db_store、db_user

1.1.4.6. 插入数据测试

分片表users
通过mycat连接db_user库,执行如下SQL
insertdb_user_users.sql

INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('1', '张1', '13611111111', '31', '2', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('2', '王二', '13622222222', '32', '5', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('3', '李三', '13633333333', '33', '3', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('4', '赵四', '13644444444', '34', '1', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('5', '田五', '13655555555', '35', '3', '2018-10-10 13:39:41', '2018-10-10 13:39:41');

ER表user_address
insertdb_user_user_address.sql

INSERT INTO `user_address`(addressID,receiver,addressDetail,userID,createTime,lastUPdate) VALUE ('1', '张一', '深圳南山科技园', '1', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `user_address`(addressID,receiver,addressDetail,userID,createTime,lastUPdate) VALUE ('2', '张一', '深圳龙华地铁站', '1', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `user_address`(addressID,receiver,addressDetail,userID,createTime,lastUPdate) VALUE ('3', '王二', '长沙麓谷软件园', '2', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `user_address`(addressID,receiver,addressDetail,userID,createTime,lastUPdate) VALUE ('4', '赵四', '长沙麓谷企业广场', '4', '2018-10-10 13:46:36', '2018-10-10 13:46:36');
INSERT INTO `user_address`(addressID,receiver,addressDetail,userID,createTime,lastUPdate) VALUE ('5', '李三', '深圳福田侨香', '3', '2018-10-10 13:46:36', '2018-10-10 13:46:36');

全局表data_dictionary
mycat上插入数据

INSERT INTO `data_dictionary`(dataDictionaryID,displayName,value,createTime,lastUpdate) VALUE ('1', '白银', 'BY', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `data_dictionary`(dataDictionaryID,displayName,value,createTime,lastUpdate) VALUE ('2', '黄金', 'HJ', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `data_dictionary`(dataDictionaryID,displayName,value,createTime,lastUpdate) VALUE ('3', '砖石', 'ZS', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `data_dictionary`(dataDictionaryID,displayName,value,createTime,lastUpdate) VALUE ('4', '大师', 'DS', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `data_dictionary`(dataDictionaryID,displayName,value,createTime,lastUpdate) VALUE ('5', '王者', 'WZ', '2018-10-10 13:39:41', '2018-10-10 13:39:41');

全局表每个节点的数据都一样

db_store测试
insert_db_store_store.sql

INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (1, '深圳宝安区圣淘沙店', '宝安区圣淘沙骏园5栋18号商铺', '20170413101010', '20170413101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (2, '深圳罗湖区红宝路1店', '罗湖区红宝路112号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (3, '深圳福田区梅华路店', '福田区上梅林梅华路上梅林菜场斜对面', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (4, '深圳福田区景田店', '福田区景田西住宅区七栋首层(民润超对面)', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (5, '深圳宝安区富通苑店', '宝安区新安街道48区富通苑A栋115号', '20170413101010', '20170413101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (6, '深圳罗湖区海富花园店', '罗湖区深南东路海富花园福怡阁底层A8铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (7, '深圳龙岗区四季花城店', '龙岗区坂田四季花城B19号商铺', '20180131101010', '20180131101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (8, '深圳南山区蔚蓝海岸店', '南山区登良路蔚蓝海岸商铺B09号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (9, '深圳福田区中康路店', '福田区上梅林中康路梅林医院斜对面振业梅苑B栋110号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (10, '深圳罗湖区松泉山庄店', '罗湖区太白路松泉山庄4栋6栋楼裙碧涟阁首层商场103-3号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (11, '深圳福田区沙嘴店', '福田区沙嘴村1坊96号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (12, '深圳宝安区桃源居3店', '宝安区前进路桃源居48区', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (13, '深圳南山区学府店', '南山区后海大道西宏观苑商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (14, '深圳福田区车公庙店', '福田区泰然工贸园四路105栋首层(泰康轩旁)', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (15, '深圳福田区金地店', '福田区金地一路金海丽名居102号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (16, '深圳罗湖区龙园山庄店', '罗湖区龙园山庄1栋102A', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (17, '深圳福田区天然居店', '福田区翔名苑B—8A商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (18, '深圳宝安区三联路店', '宝安区龙华镇三联路181号一楼右层', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (19, '深圳宝安区深业新岸线店', '宝安区深业新岸线2栋11号铺', '20170413101010', '20170413101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (20, '深圳宝安区风和日丽店', '宝安区龙华镇丰润花园13栋21号铺', '20171016101010', '20171016101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (21, '深圳龙岗区茂盛路店', '龙岗区横岗镇茂盛路16号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (22, '深圳南山区西海湾店', '南山区南商路西海湾花园单身公寓A4号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (23, '深圳南山区招商海月店', '南山区后海路招商海月花园24栋1-1', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (24, '深圳罗湖区布心店', '罗湖区布心村太白路1号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (25, '深圳宝安区美丽365花园店', '宝安区龙华镇东环一路美丽365花园B2栋102商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (26, '深圳南山区阳光棕榈园店', '南山区阳光棕榈园商业街九栋105室', '20180404101010', '20180404101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (27, '深圳宝安区天骄店', '宝安区天骄世家花园125#商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (28, '深圳宝安区东源阁店', '宝安区龙华镇东环二路东源阁C区一栋112商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (29, '深圳福田区中信广场店', '福田区同心路铺尾村54栋103号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (30, '深圳福田区碧海云天店', '福田白石洲路以北红树东方家园15栋一层商场10#', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (31, '深圳宝安区建安新村店', '宝安区西乡镇上川路建安新村104号铺', '20170413101010', '20170413101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (32, '深圳福田区益田村店', '福田区益田路1005号益田村(高层区)108栋1层105A号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (33, '新安湖店(停用)', NULL, '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (34, '深圳南山区南山市场店', '南山区南新路2025号之二', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (35, '上沙东村店(停用)', '福田区农轩路农科中心', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (36, '深圳宝安区桃源居1店', '宝安区前进路桃源居4区1栋117号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (37, '深圳福田区梅兴苑店', '福田区梅华路梅兴苑四栋13号铺', '20180404101010', '20180404101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (38, '深圳南山区缤纷店(停)', '深圳市南山区缤纷假日广场125号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (39, '深圳福田区莲花一村店', '福田区莲花一村17栋附一楼', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (40, '深圳宝安区富通天骏店', '宝安区龙华镇和平路富通天骏12号', '20171016101010', '20171016101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (41, '深圳罗湖区蔡屋围店', '罗湖区书城路蔡屋围新八坊41栋南', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (42, '深圳宝安区新境园店', '宝安区民治街梅龙南路东侧阳光新境园三栋一层2号', '20171016101010', '20171016101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (43, '深圳南山区育德佳园店(停用)', '南山区后海路育德佳园2栋10号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (44, '深圳福田区新洲一街店', '福田区新洲北村32号一楼南铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (45, '深圳宝安区缤纷世界店', '宝安区兴业路富通城一期B2栋125号商铺', '20170413101010', '20170413101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (46, '深圳龙岗区百合山庄店', '龙岗区布吉日尾坑百合山庄百薇苑142号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (47, '深圳宝安区景龙新村店', '宝安区龙华镇宝华路景龙新村', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (48, '深圳宝安区榕苑店', '宝安区龙华镇民治路榕苑花园', '20180404101010', '20180404101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (49, '深圳南山区明星店', '南山区前海路星海名城七组团4栋41号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (50, '深圳福田区福源店', '福田区彩田路福源大厦2014-15号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (51, '深圳龙岗区长龙路店', '龙岗区布吉长龙路113号B门面', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (52, '黄贝岭店(停)', '黄贝岭下村310栋', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (53, '深圳福田区梅林一村店', '福田区下梅林围面村1-2号102', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (54, '香榭里店(停用)', '福田区农轩路农科中心', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (55, '皇御苑店(停)', '福田区皇御苑B区7栋至11栋裙楼', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (56, '深圳福田区田面店', '福田区田面花园西侧', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (57, '深圳罗湖区松园店', '罗湖区松园路2号楼3号铺(红岭小学对面)', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (58, '皇岗新村店(停用)', '福田区皇岗新村25号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (59, '深圳宝安区水斗富豪店', '宝安区龙华镇水斗富豪新村二巷8号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (60, '深圳宝安区皇庭世纪店(停用)', '福田区皇岗村吉龙二村65号102铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (61, '深圳南山区海滨店', '南山区高新南路11道彩虹之岸商铺112号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (62, '深圳宝安区西城上筑店', '宝安区西城上筑花园1栋1-119号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (63, '深圳宝安区天悦龙庭店', '宝安区天悦龙庭B栋128号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (64, '深圳龙岗区康桥花园店', '龙岗区布吉镇中城康桥花园(二期)青之源17栋107', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (65, '深圳福田区宝田苑店', '福田区福强路宝田苑5B商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (66, '深圳龙岗区可园1店', '龙岗区可园社区13栋107铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (67, '深圳罗湖区渔民村店', '罗湖区渔民村商铺6C', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (68, '深圳福田区紫竹四路店', '福田区竹子林育星苑一栋首层C商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (69, '深圳宝安区民乐花园店', '宝安区民乐花园19栋103号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (70, '深圳罗湖区松泉公寓店', '罗湖区太白路松泉公寓17栋1楼A011号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (71, '深圳罗湖区田心村店', '罗湖区宝岗路田心村田心大厦1楼4号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (72, '潜龙鑫茂店(停)', '龙华潜龙鑫茂花园', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (73, '深圳龙岗区布吉莲花1店', '龙岗区布吉镇布吉莲花100号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (74, '深圳南山区现代城店', '南山区南光路现代华庭6栋1单元104号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (75, '金色花园店', '福田区莲花路金色家园3期裙楼A02B', '20180811101010', '20180811101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (76, '深圳福田区翰岭苑店', '福田区翰岭花园1-2栋裙楼113号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (77, '深圳福田区百花三路店', '福田区百花三路南天2栋106B商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (78, '滨海之窗店(停)', NULL, '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (79, '深圳宝安区滢水山庄店', '宝安区滢水山庄二区8栋106', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (80, '深圳罗湖区莲塘国威店', '罗湖区莲塘国威路聚宝路182号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (81, '深圳罗湖区宝安南路店', '罗湖区宝安南2015号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (82, '百乐汇店中店', NULL, '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (83, '深圳龙岗区翠枫豪园店', '龙岗区布吉翠峰豪园1005号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (84, '深圳宝安区富士康1店', '宝安区龙华油松第十工业区东环二路二号富士康L1区商业街1楼第9号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (85, '深圳福田区新洲二街店', '福田区新洲村新洲二街绿景新苑10号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (86, '深圳宝安区锦绣江南店', '宝安区民治街道锦绣江南B1148号商铺', '20171016101010', '20171016101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (87, '测试门店1', NULL, '20180926101010', '20180926101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (88, '深圳宝安区观澜格澜郡店', '宝安区观澜街道观澜郡一期A02号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (89, '深圳龙岗区东大街1店', '龙岗区布吉东大街中翠花园111铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (90, '深圳福田区丽阳天下店', '福田区石厦路缔馨园裙楼111号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (91, '深圳宝安区桃源居2店(停)', '深圳市宝安区前进路桃源居118号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (92, '深圳福田区沙嘴2店(停)', '福田区', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (93, '深圳龙岗区丽湖花园店', '深圳市龙岗区丽湖花园湖彩阁9号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (94, '深圳宝安区龙泉花园店', '宝安区龙华龙泉花园A14号铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (95, '深圳罗湖区中兴路店', '罗湖区中兴路103号商铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (96, '深圳龙岗区东大街2店', '龙岗区布吉东大街桂芳园7区29栋D102铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (97, '深圳罗湖区莲塘聚福路店', '罗湖区莲塘聚福路鹏兴花园56栋114铺', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (98, '深圳南山区东滨路店', '南山区东滨路蛇口兰园大厦15A', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (99, '深圳福田区国都高尔夫花园店', '福田区新沙路国都高尔夫花园翠逸阁1层107C号', '20170330101010', '20170330101010');
INSERT INTO `store` (`storeID`, `storeName`, `storeAddress`, `createTime`, `lastUpdate`) VALUES (100, '东莞市中信凯旋城', '东莞市东城区火炼树怡丰都市广场怡祥阁B2铺', '20180223180232', '20180223180232');

1.1.5. 配置详解

1.1.5.1. rule规则详解

 常用的分片规则:总共十个(基本够用)
一、枚举法
<tableRule name="sharding-by-intfile">
    <rule>
      <columns>user_id</columns>
      <algorithm>hash-int</algorithm>
    </rule>
  </tableRule>
<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
    <property name="mapFile">partition-hash-int.txt</property>
    <property name="type">0</property>
    <property name="defaultNode">0</property>
  </function>
 
partition-hash-int.txt 配置:
10000=0
10010=1
上面columns 标识将要分片的表字段,algorithm 分片函数,
其中分片函数配置中,mapFile标识配置文件名称,type默认值为0,0表示Integer,非零表示String,
所有的节点配置都是从0开始,及0代表节点1
/**
*  defaultNode 默认节点:小于0表示不设置默认节点,大于等于0表示设置默认节点,结点为指定的值
* 
默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点
*                如果不配置默认节点(defaultNode值小于0表示不配置默认节点),碰到
*                不识别的枚举值就会报错,
*                like this:can't find datanode for sharding column:column_name val:ffffffff    
*/
 
二、固定分片hash算法
<tableRule name="rule1">
    <rule>
      <columns>user_id</columns>
      <algorithm>func1</algorithm>
    </rule>
</tableRule>
 
  <function name="func1" class="io.mycat.route.function.PartitionByLong">
    <property name="partitionCount">2,1</property>
    <property name="partitionLength">256,512</property>
  </function>
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,
partitionCount 分片个数列表,partitionLength 分片范围列表
分区长度:默认为最大2^n=1024 ,即最大支持1024分区
约束 :
count,length两个数组的长度必须是一致的。
1024 = sum((count[i]*length[i])). count和length两个向量的点积恒等于1024
用法例子:
@Test
public void testPartition() {
// 本例的分区策略:希望将数据水平分成3份,前两份各占25%,第三份占50%。(故本例非均匀分区)
// |<---------------------1024------------------------>|
// |<----256--->|<----256--->|<----------512---------->|
// | partition0 | partition1 | partition2 |
// | 共2份,故count[0]=2 | 共1份,故count[1]=1 |
int[] count = new int[] { 2, 1 };
int[] length = new int[] { 256, 512 };
PartitionUtil pu = new PartitionUtil(count, length);

// 下面代码演示分别以offerId字段或memberId字段根据上述分区策略拆分的分配结果
int DEFAULT_STR_HEAD_LEN = 8; // cobar默认会配置为此值
long offerId = 12345;
String memberId = "qiushuo";

// 若根据offerId分配,partNo1将等于0,即按照上述分区策略,offerId为12345时将会被分配到partition0中
int partNo1 = pu.partition(offerId);

// 若根据memberId分配,partNo2将等于2,即按照上述分区策略,memberId为qiushuo时将会被分到partition2中
int partNo2 = pu.partition(memberId, 0, DEFAULT_STR_HEAD_LEN);

Assert.assertEquals(0, partNo1);
Assert.assertEquals(2, partNo2);
}
 
如果需要平均分配设置:平均分为4分片,partitionCount*partitionLength=1024
<function name="func1" class="org.opencloudb.route.function.PartitionByLong">
    <property name="partitionCount">4</property>
    <property name="partitionLength">256</property>
  </function>
 
三、范围约定
<tableRule name="auto-sharding-long">
    <rule>
      <columns>user_id</columns>
      <algorithm>rang-long</algorithm>
    </rule>
  </tableRule>
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
    <property name="mapFile">autopartition-long.txt</property>
  </function>
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
或
0-10000000=0
10000001-20000000=1
 
 
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,
rang-long 函数中mapFile代表配置文件路径
所有的节点配置都是从0开始,及0代表节点1,此配置非常简单,即预先制定可能的id范围到某个分片
 
四、求模法
<tableRule name="mod-long">
    <rule>
      <columns>user_id</columns>
      <algorithm>mod-long</algorithm>
    </rule>
  </tableRule>
  <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
   <!-- how many data nodes  -->
    <property name="count">3</property>
  </function>
 
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,
此种配置非常明确即根据id与count(你的结点数)进行求模预算,相比方式1,此种在批量插入时需要切换数据源,id不连续
 
五、日期列分区法
<tableRule name="sharding-by-date">
      <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-date</algorithm>
      </rule>
   </tableRule> 
<function name="sharding-by-date" class="io.mycat.route.function..PartitionByDate">
   <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sBeginDate">2014-01-01</property>
    <property name="sPartionDay">10</property>
  </function>
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,
配置中配置了开始日期,分区天数,即默认从开始日期算起,分隔10天一个分区
 
还有一切特性请看源码
 
 
Assert.assertEquals(true, 0 == partition.calculate("2014-01-01"));
Assert.assertEquals(true, 0 == partition.calculate("2014-01-10"));
Assert.assertEquals(true, 1 == partition.calculate("2014-01-11"));
Assert.assertEquals(true, 12 == partition.calculate("2014-05-01"));
 
 
 
六、通配取模
<tableRule name="sharding-by-pattern">
      <rule>
        <columns>user_id</columns>
        <algorithm>sharding-by-pattern</algorithm>
      </rule>
   </tableRule>
<function name="sharding-by-pattern" class="io.mycat.route.function.PartitionByPattern">
    <property name="patternValue">256</property>
    <property name="defaultNode">2</property>
    <property name="mapFile">partition-pattern.txt</property>
 
  </function>
partition-pattern.txt 
# id partition range start-end ,data node index
###### first host configuration
1-32=0
33-64=1
65-96=2
97-128=3
######## second host configuration
129-160=4
161-192=5
193-224=6
225-256=7
0-0=7
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,patternValue 即求模基数,defaoultNode 默认节点,如果不配置了默认,则默认是0即第一个结点
mapFile 配置文件路径
配置文件中,1-32 即代表id%256后分布的范围,如果在1-32则在分区1,其他类推,如果id非数字数据,则会分配在defaoultNode 默认节点
 
 
String idVal = "0";
Assert.assertEquals(true, 7 == autoPartition.calculate(idVal));
idVal = "45a";
Assert.assertEquals(true, 2 == autoPartition.calculate(idVal));
 
七、ASCII码求模通配
<tableRule name="sharding-by-prefixpattern">
      <rule>
        <columns>user_id</columns>
        <algorithm>sharding-by-prefixpattern</algorithm>
      </rule>
   </tableRule>
<function name="sharding-by-pattern" class="io.mycat.route.function.PartitionByPrefixPattern">
    <property name="patternValue">256</property>
    <property name="prefixLength">5</property>
    <property name="mapFile">partition-pattern.txt</property>
 
  </function>
 
partition-pattern.txt
 
# range start-end ,data node index
# ASCII
# 48-57=0-9
# 64、65-90=@、A-Z
# 97-122=a-z
###### first host configuration
1-4=0
5-8=1
9-12=2
13-16=3
###### second host configuration
17-20=4
21-24=5
25-28=6
29-32=7
0-0=7
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,patternValue 即求模基数,prefixLength ASCII 截取的位数
mapFile 配置文件路径
配置文件中,1-32 即代表id%256后分布的范围,如果在1-32则在分区1,其他类推 
 
此种方式类似方式6只不过采取的是将列种获取前prefixLength位列所有ASCII码的和进行求模sum%patternValue ,获取的值,在通配范围内的
即 分片数,
/**
* ASCII编码:
* 48-57=0-9阿拉伯数字
* 64、65-90=@、A-Z
* 97-122=a-z
*
*/
如 
 
String idVal="gf89f9a";
Assert.assertEquals(true, 0==autoPartition.calculate(idVal));

idVal="8df99a";
Assert.assertEquals(true, 4==autoPartition.calculate(idVal));

idVal="8dhdf99a";
Assert.assertEquals(true, 3==autoPartition.calculate(idVal));
 
八、编程指定
<tableRule name="sharding-by-substring">
      <rule>
        <columns>user_id</columns>
        <algorithm>sharding-by-substring</algorithm>
      </rule>
   </tableRule>
<function name="sharding-by-substring" class="io.mycat.route.function.PartitionDirectBySubString">
    <property name="startIndex">0</property> <!-- zero-based -->
    <property name="size">2</property>
    <property name="partitionCount">8</property>
    <property name="defaultPartition">0</property>
  </function>
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数 
此方法为直接根据字符子串(必须是数字)计算分区号(由应用传递参数,显式指定分区号)。
例如id=05-100000002
在此配置中代表根据id中从startIndex=0,开始,截取siz=2位数字即05,05就是获取的分区,如果没传默认分配到defaultPartition
 
九、字符串拆分hash解析
<tableRule name="sharding-by-stringhash">
      <rule>
        <columns>user_id</columns>
        <algorithm>sharding-by-stringhash</algorithm>
      </rule>
   </tableRule>
<function name="sharding-by-substring" class="io.mycat.route.function.PartitionByString">
    <property name=length>512</property> <!-- zero-based -->
    <property name="count">2</property>
    <property name="hashSlice">0:2</property>
  </function>
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数 
函数中length代表字符串hash求模基数,count分区数,hashSlice hash预算位
即根据子字符串 hash运算
 
hashSlice : 0 means str.length(), -1 means str.length()-1
 
/**
     * "2" -&gt; (0,2)<br/>
     * "1:2" -&gt; (1,2)<br/>
     * "1:" -&gt; (1,0)<br/>
     * "-1:" -&gt; (-1,0)<br/>
     * ":-1" -&gt; (0,-1)<br/>
     * ":" -&gt; (0,0)<br/>
     */
public class PartitionByStringTest {

@Test
public void test() {
PartitionByString rule = new PartitionByString();
String idVal=null;
rule.setPartitionLength("512");
rule.setPartitionCount("2");
rule.init();
rule.setHashSlice("0:2");
//    idVal = "0";
//    Assert.assertEquals(true, 0 == rule.calculate(idVal));
//    idVal = "45a";
//    Assert.assertEquals(true, 1 == rule.calculate(idVal));



//last 4
rule = new PartitionByString();
rule.setPartitionLength("512");
rule.setPartitionCount("2");
rule.init();
//last 4 characters
rule.setHashSlice("-4:0");
idVal = "aaaabbb0000";
Assert.assertEquals(true, 0 == rule.calculate(idVal));
idVal = "aaaabbb2359";
Assert.assertEquals(true, 0 == rule.calculate(idVal));
}
 
十、一致性hash
<tableRule name="sharding-by-murmur">
      <rule>
        <columns>user_id</columns>
        <algorithm>murmur</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>

1.1.5.2. schema.xml

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


	<!--
	name:为mycat逻辑库的名字,对应server<property name="schemas">mydatabase</property>,
	建议设置跟数据库一样的名称
	checkSQLschema:自动检查逻辑库名称并拼接,true会在sql语句中的表名前拼接逻辑库名,
	例如select * from mydatabase.t_user;
	sqlMaxLimit:查询保护、如果没有写limit条件,会自动拼接。只查询100条。
	-->
	<schema name="mydatabase" checkSQLschema="true" sqlMaxLimit="100">
		<!--
		name:为物理数据库的表名,命名与物理数据库的一致 
		dataNode:为dataNode标签(<dataNode name="dn1" dataHost="dtHost1" database="db1" />)里面的name值
		dataNode里面填写的节点数量必须和rule里面的规则数量一致
		例如rule里面只定义了两个0-1M=0  1M-2M=1那么此处只可以指定两个节点,1M=10000,M为单位万
		primaryKey:为表的ID字段,建议和rule.xml里面指定的ID和物理库的ID一致
		rule:分片规则,对应rule.xml中<tableRule name="student_id">的name
		type:表格类型,默认非global,用于全局表定义
		-->
		<table name="t_user" dataNode="dn1,dn2,dn3" primaryKey="id" rule="auto-sharding-long">
			<!--ER分片注意childTable 标签需要放到table标签内,是主外键关联关系,
				name:为物理数据库的表名,命名与物理数据库的一致 
				primaryKey:为表t_loginlog的ID字段,建议和rule.xml里面指定的ID和物理库的ID一致.
				joinKey:从表t_loginlog的外键字段,需要和物理库的字段名称一致
				parentKey:为主表t_user的字段名,依据此字段做关联,进行ER分片
			-->		
			<childTable name="t_loginlog" primaryKey="id" joinKey="user_id" parentKey="id"></childTable>
		</table>
		<table name="t_student" dataNode="dn1,dn3" primaryKey="id" rule="student_id" />
		<table name="t_dictionaries" dataNode="dn1,dn2,dn3" type="global" />
		<table name="t_teacher" dataNode="dn1" />
    </schema>
		
		<!-- name:节点名称,用于在table标签里面调用
		dataHost:dataHost标签name值(<dataHost name="dtHost1">)
		database:物理数据库名,需要提前创建好实际存在的-->
		<dataNode name="dn1" dataHost="dtHost1" database="db1" />
		<dataNode name="dn2" dataHost="dtHost1" database="db2" />
		<dataNode name="dn3" dataHost="dtHost2" database="db3" />
		
	<!--
	name:节点名称,在上方dataNode标签中调用
	maxCon:底层数据库的链接最大数
	minCon:底层数据库的链接最小数
	balance:值可以为0,1,2,3,分别表示对当前datahost中维护的数据库们的读操作逻辑
	0:不开启读写分离,所有的读写操作都在最小的索引号的writeHost(第一个writeHost标签)
	1:全部的readHost和备用writeHost都参与读数据的平衡,如果读的请求过多,负责写的第一个writeHost也分担一部分
	2 :所有的读操作,都随机的在所有的writeHost和readHost中进行
	3 :所有的读操作,都到writeHost对应的readHost上进行(备用writeHost不参加了),在集群中没有配置ReadHost的情况下,读都到第
	一个writeHost完成
	writeType:控制当前datahost维护的数据库集群的写操作
	0:所有的写操作都在第一个writeHost标签的数据库进行
	1:所有的写操作,都随机分配到所有的writeHost(mycat1.5完全不建议配置了)
	dbtype:数据库类型(不同数据库配置不同名称,mysql)
	dbDriver:数据库驱动,native,动态获取
	switchType:切换的逻辑
	-1:故障不切换
	1:故障切换,当前写操作的writeHost故障,进行切换,切换到下一个writeHost;
	slaveThreshold:标签中的<heartbeat>用来检测后端数据库的心跳sql语句;本属性检查从节点与主节点的同步情况(延迟时间数),配合心
	跳语句show slave status; 读写分离时,所有的readHost的数据都可靠
	-->
	<dataHost name="dtHost1" maxCon="1000" minCon="10" balance="1"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<!--用于验证心跳,这个是mysql主库的配置-->
		<heartbeat>select user()</heartbeat>
		
		<writeHost host="127.0.0.1" url="192.168.199.11:3306" user="root" password="123456">
			<readHost host="127.0.0.1" url="192.168.199.12:3306" user="root" password="123456" />
		</writeHost>
	
	</dataHost>
	<dataHost name="dtHost2" maxCon="1000" minCon="10" balance="1"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<!--用于验证心跳,这个是mysql主库的配置-->
		<heartbeat>select user()</heartbeat>
		
		<writeHost host="127.0.0.1" url="192.168.199.13:3306" user="root" password="123456">
			<readHost host="127.0.0.1" url="192.168.199.13:3306" user="root" password="123456" />
		</writeHost>
	
	</dataHost>
</mycat:schema>

1.1.5.3. 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="serverPort">8066</property>
	<property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
	<property name="useHandshakeV10">1</property>
	<property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
	<property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->

		<property name="sequnceHandlerType">2</property>
	<property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
      <!--  <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="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">1</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>
		
	</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账户登录-->
	<!-- 此处是开放了本机和外网的请求链接,因为我的mycat安装在虚拟机上,所以本机是通过ip链接
	192.*是为了让navicat可以连接使用(配置完整的虚拟机IP也可以)
	127.*是为了让虚拟机本身可以通过命令连接-->
	<firewall>
	   <whitehost>
	      <host host="192.*" user="root"/>
		  <host host="127.*" user="root"/>
	   </whitehost>
       <blacklist check="false">
       </blacklist>
	</firewall>
	
	<!-- 此处定义了一个root用户,可以管理的逻辑库为mydatabase,对应schema.xml中的<schema name="mydatabase" > -->
	<user name="root" defaultAccount="true">
		<property name="password">123456</property>
		<property name="schemas">mydatabase</property>
		
		<!-- 表级 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="user">
		<property name="password">123456</property>
		<property name="schemas">mycat1,test3</property>
		<property name="readOnly">true</property>
	</user>-->

</mycat:server>

1.1.5.4. 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/">
<!--schema.xml中配置的rule="student_id" 所对应的规则,规则对应主键,
列名为id需要与数据库的列名对应algorithm对应下方function-->
	<tableRule name="student_id">
        <rule>
            <columns>id</columns>
            <algorithm>student_text</algorithm>
        </rule>
    </tableRule>
	
	
	<tableRule name="rule1">
		<rule>
			<columns>id</columns>
			<algorithm>func1</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>




<!--在conf中需要添加student_text.txt规则文件-->
 <function name="student_text"
        class="io.mycat.route.function.AutoPartitionByLong">
        <property name="mapFile">student_text.txt</property>
    </function>
	
	
	
	
	
	
	
	
	<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">
	</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="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>

1.2. 读写分离实现

1.3. 常见报错

1.3.1. 启动常见报错:

INFO   | jvm 1    | 2021/02/09 15:34:54 | WrapperSimpleApp Usage:
INFO   | jvm 1    | 2021/02/09 15:34:54 |   java org.tanukisoftware.wrapper.WrapperSimpleApp {app_class} [app_arguments]
INFO   | jvm 1    | 2021/02/09 15:34:54 |
INFO   | jvm 1    | 2021/02/09 15:34:54 | Where:
INFO   | jvm 1    | 2021/02/09 15:34:54 |   app_class:      The fully qualified class name of the application to run.
INFO   | jvm 1    | 2021/02/09 15:34:54 |   app_arguments:  The arguments that would normally be passed to the
INFO   | jvm 1    | 2021/02/09 15:34:54 |                   application.

以上报错安装jdk8的版本即可处理

1.3.2. ERROR 1152 (HY000): java.lang.IllegalArgumentException: Invalid DataSource:0

问题分析:无效的数据源,我这的情况是由于mycat的逻辑库无法获得真实库的数据导致的错误。

20190808150007874
问题解决:我这新安装的mysql(Percona),在设置本地登录root/root用户权限后:mysqladmin -uroot password ‘root’,没有给mysql其它通过ip或者本地127.0.0.1登录方式添加密码,因此如果通过mycat登录时有密码的话,就匹配不上,所以mycat无法获取源数据库的数据导致错误,只要通过SQLyog登录上mysql的user表格(mysql->user),直接localhost上密码复制到其它ip、127.0.0.1等行password上就好了。顺手直接把其它的登录方式密码也直接复制粘贴并保存,重新启动数据库:service mysql restart 。就可以通过mycat重新连接上了。或者通过命令行登录上mysql去修改对应表格。

1.3.3. no route to host

防火墙问题