概念 | 含义 |
主机
|
物理主机,一台服务器,一个数据库服务,一个 3306 端口
|
物理数据库
|
真实的数据库,例如 146、150、151 的 gpcat 数据库
|
物理表
|
真实的表,例如 146、150、151 的 gpcat 数据库的 order_info 表
|
分片
|
将原来单个数据库的数据切分后分散存储在不同的数据库节点
|
分片节点
|
分片以后数据存储的节点
|
分片键
|
分片依据的字段,例如 order_info 表以 id 为依据分片,id 就是分片键,通常是主键
|
分片算法
|
分片的规则,例如随机、取模、范围、哈希、枚举以及各种组合算法
|
逻辑表
|
相对于物理表,是分片表聚合后的结果,对于客户端来说跟真实的表没有区别
|
逻辑数据库
|
相对于物理数据库,是数据节点聚合后的结果,例如 catmall
|
wget http://dl.mycat.io/1.6.7.3/20190927161129/Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz tar -xzvf Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz
目录 | 作用 |
bin
|
启动目录
|
catlet
|
空目录
|
conf
|
配置目录
|
lib
|
jar 包依赖
|
logs
|
日志目录
|
<user name="root" defaultAccount="true"> <property name="password">123456</property> <property name="schemas">catmall</property> </user>
java -cp Mycat-server-1.6.7.3-release.jar io.mycat.util.DecryptUtil 0:root:123456
<schema name="catmall" checkSQLschema="false" sqlMaxLimit="100"> <!-- 范围分片 --> <table name="customer" primaryKey="id" dataNode="dn1,dn2,dn3" rule="rang-long-cust" /> <!-- 取模分片 --> <table name="order_info" dataNode="dn1,dn2,dn3" rule="mod-long-order" > <!-- ER 表 --> <childTable name="order_detail" primaryKey="id" joinKey="order_id" parentKey="order_id"/> </table> <!-- 全局表 --> <table name="student" primaryKey="sid" type="global" dataNode="dn1,dn2,dn3" /> </schema>
配置 |
作用
|
primaryKey
|
指定该逻辑表对应真实表的主键。MyCat 会缓存主键(通过 primaryKey 属性配置)与
具体 dataNode 的信息。
当分片规则(rule)使用非主键进行分片时,那么在使用主键进行查询时,MyCat 就
会通过缓存先确定记录在哪个 dataNode 上,然后再在该 dataNode 上执行查询。
如果没有缓存/缓存并没有命中的话,还是会发送语句给所有的 dataNode。
|
dataNode
|
数据分片的节点
|
autoIncrement
|
自增长(全局序列),true 代表主键使用自增长策略
|
type
|
全局表:global。其他:不配置
|
<dataNode name="dn1" dataHost="host1" database="gpcat" />
<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="localhost:3306" user="root" password="123456"> <!-- can have multi read hosts --> <readHost host="hostS2" url="192.168.8.146:3306" user="root" password="xxx" /> </writeHost> <writeHost host="hostS1" url="localhost:3316" user="root" password="123456" /> <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </dataHost>
值 | 作用 |
0 |
不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。
|
1 |
所有读操作都随机发送到当前的 writeHost 对应的 readHost 和备用的 writeHost
|
2 |
所有的读操作都随机发送到所有的 writeHost,readHost 上
|
3 |
所有的读操作都只发送到 writeHost 的 readHost 上
|
值 | 作用 |
0 |
所有写操作都发送到可用的 writeHost 上(默认第一个,第一个挂了以后发到第二个)
|
1 |
所有写操作都随机的发送到 writeHost
|
值 | 作用 |
-1 |
表示不自动切换
|
1 |
默认值,表示自动切换
|
2 |
基于 MySQL 主从同步的状态决定是否切换,心跳语句为 show slave status
|
3 |
基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1),心跳语句为 show status like ‘wsrep%‘。
|
<tableRule name="rang-long-cust"> <rule> <columns>id</columns> <algorithm>func-rang-long-cust</algorithm> </rule> </tableRule>
<function name="func-rang-long-cust" class="io.mycat.route.function.AutoPartitionByLong"> <property name="mapFile">rang-long-cust.txt</property> </function
10001-20000=1 0-10000=0 20001-100000=2
cd /usr/local/soft/mycat/conf cp *.txt *.xml *.properties zkconf/ cd /usr/local/soft/mycat/bin ./init_zk_data.sh
loadZk=true zkURL=127.0.0.1:2181 clusterId=010 myid=01001 clusterSize=1 clusterNodes=mycat_gp_01 #server booster ; booster install on db same server,will reset all minCon to 2 type=server boosterDataHosts=dataHost1
操作 | 命令 |
启动
|
./mycat start
|
停止
|
./mycat stop
|
重启
|
./mycat restart
|
查看状态
|
./mycat status
|
前台运行
|
./mycat console
|
mysql -uroot -p123456 -h 192.168.8.151 -P8066 catmall
CREATE TABLE `customer` ( `id` INT (11) DEFAULT NULL, `name` VARCHAR (255) DEFAULT NULL ) ENGINE = INNODB DEFAULT CHARSET = utf8;
CREATE TABLE `order_info` ( `order_id` INT (11) NOT NULL COMMENT ‘订单 ID‘, `uid` INT (11) DEFAULT NULL COMMENT ‘用户 ID‘, `nums` INT (11) DEFAULT NULL COMMENT ‘商品数量‘, `state` INT (2) DEFAULT NULL COMMENT ‘订单状态‘, `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT ‘创建时间‘, `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新时间‘, PRIMARY KEY (`order_id`) ) ENGINE = INNODB DEFAULT CHARSET = utf8;
CREATE TABLE `order_detail` ( `order_id` INT (11) NOT NULL COMMENT ‘订单号‘, `id` INT (11) NOT NULL COMMENT ‘订单详情‘, `goods_id` INT (11) DEFAULT NULL COMMENT ‘货品 ID‘, `price` DECIMAL (10, 2) DEFAULT NULL COMMENT ‘价格‘, `is_pay` INT (2) DEFAULT NULL COMMENT ‘支付状态‘, `is_ship` INT (2) DEFAULT NULL COMMENT ‘是否发货‘, `status` INT (2) DEFAULT NULL COMMENT ‘订单详情状态‘, PRIMARY KEY (`order_id`, `id`) ) ENGINE = INNODB DEFAULT CHARSET = utf8;
CREATE TABLE `student` ( `sid` INT (8) NOT NULL AUTO_INCREMENT, `name` VARCHAR (255) DEFAULT NULL, `qq` VARCHAR (255) DEFAULT NULL, PRIMARY KEY (`sid`) ) ENGINE = INNODB DEFAULT CHARSET = utf8;
<table name="customer" dataNode="dn1,dn2,dn3" rule="rang-long-cust" primaryKey="id" /> <table name="order_info" dataNode="dn1,dn2,dn3" rule="mod-long-order"> <childTable name="order_detail" joinKey="order_id" parentKey="order_id" primaryKey="id" /> </table> <table name="student" dataNode="dn1,dn2,dn3" primaryKey="sid" type="global" />
<dataNode name="dn1" dataHost="host1" database="gpcat" /> <dataNode name="dn2" dataHost="host2" database="gpcat" /> <dataNode name="dn3" dataHost="host3" database="gpcat" /> <dataHost balance="0" maxCon="1000" minCon="10" name="host1" writeType="0" switchType="1" slaveThreshold="100" dbType="mysql" dbDriver="native"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="192.168.8.146:3306" password="123456" user="root" /> </dataHost> <dataHost balance="0" maxCon="1000" minCon="10" name="host2" writeType="0" switchType="1" slaveThreshold="100" dbType="mysql" dbDriver="native"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="192.168.8.150:3306" password="123456" user="root" /> </dataHost> <dataHost balance="0" maxCon="1000" minCon="10" name="host3" writeType="0" switchType="1" slaveThreshold="100" dbType="mysql" dbDriver="native"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="192.168.8.151:3306" password="123456" user="root" /> </dataHost>
<tableRule name="rang-long-cust"> <rule> <columns>id</columns> <algorithm>rang-long-cust</algorithm> </rule> </tableRule>
<function name="rang-long-cust" class="io.mycat.route.function.AutoPartitionByLong"> <property name="mapFile">rang-long-cust.txt</property> </function>
INSERT INTO `customer` (`id`, `name`) VALUES (6666, ‘赵先生‘); INSERT INTO `customer` (`id`, `name`) VALUES (7777, ‘钱先生‘); INSERT INTO `customer` (`id`, `name`) VALUES (16666, ‘孙先生‘); INSERT INTO `customer` (`id`, `name`) VALUES (17777, ‘李先生‘); INSERT INTO `customer` (`id`, `name`) VALUES (26666, ‘周先生‘); INSERT INTO `customer` (`id`, `name`) VALUES (27777, ‘吴先生‘);
<tableRule name="mod-long-order"> <rule> <columns>order_id</columns> <algorithm>mod-long</algorithm> </rule> </tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod"> <property name="count">3</property> </function>
INSERT INTO `order_info` (`order_id`, `uid`, `nums`, `state`,`create_time`, `update_time`) VALUES (1, 1000001, 1, 2, ‘2019-9-23 14:35:37‘, ‘2019-9-23 14:35:37‘); INSERT INTO `order_info` (`order_id`,`uid`, `nums`, `state`, `create_time`, `update_time`) VALUES (2,1000002, 1, 2, ‘2019-9-24 14:35:37‘, ‘2019-9-24 14:35:37‘); INSERT INTO `order_info` (`order_id`, `uid`, `nums`, `state`, `create_time`,`update_time`) VALUES (3, 1000003, 3, 1, ‘2019-9-25 11:35:49‘,‘2019-9-25 11:35:49‘);
INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`,`is_pay`, `is_ship`, `status`) VALUES (3, 20180001, 85114752, 19.99, 1,1, 1); INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`,`price`, `is_pay`, `is_ship`, `status`) VALUES (1, 20180002, 25411251,1280.00, 1, 1, 0); INSERT INTO `order_detail` (`order_id`, `id`,`goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (1, 20180003,62145412, 288.00, 1, 1, 2); INSERT INTO `order_detail` (`order_id`,`id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (2,20180004, 21456985, 399.00, 1, 1, 2); INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (2, 20180005, 21457452, 1680.00, 1, 1, 2); INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`,`is_ship`, `status`) VALUES (2, 20180006, 65214789, 9999.00, 1, 1, 3);
<table name="student" dataNode="dn1,dn2,dn3" primaryKey="sid" type="global"/>
INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (1, ‘黑白‘,‘166669999‘); INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (2, ‘AV哥‘, ‘466669999‘); INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (3, ‘最强菜鸟‘, ‘368828888‘); INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (4, ‘加载中‘, ‘655556666‘); INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (5, ‘猫老公‘, ‘265286999‘); INSERT INTO `student` (`sid`, `name`, `qq`) VALUES (6, ‘一个人的精彩‘, ‘516895555‘);
<property name="sequnceHandlerType">0</property>
CUSTOMER.HISIDS= CUSTOMER.MINID=10000001 CUSTOMER.MAXID=20000000 CUSTOMER.CURID=10000001
INSERT INTO `customer` (`id`, `name`) VALUES (next value for MYCATSEQ_CUSTOMER, ‘qingshan‘);
<property name="sequnceHandlerType">1</property>
#sequence stored in datanode GLOBAL=dn1 CUSTOMER=dn1
DROP TABLE IF EXISTS MYCAT_SEQUENCE; CREATE TABLE MYCAT_SEQUENCE ( NAME VARCHAR (50) NOT NULL, current_value INT NOT NULL, increment INT NOT NULL DEFAULT 1, remark VARCHAR (100), PRIMARY KEY (NAME) ) ENGINE = INNODB;
<table name="mycat_sequence" dataNode="dn1" autoIncrement="true" primaryKey="id"></table>
DROP FUNCTION IF EXISTS `mycat_seq_currval`; DELIMITER; ; CREATE DEFINER = `root`@`%` FUNCTION `mycat_seq_currval` (seq_name VARCHAR(50)) RETURNS VARCHAR (64) CHARSET latin1 DETERMINISTIC BEGIN DECLARE retval VARCHAR (64); SET retval = "-999999999,null"; SELECT concat( CAST(current_value AS CHAR), ",", CAST(increment AS CHAR) ) INTO retval FROM MYCAT_SEQUENCE WHERE NAME = seq_name; RETURN retval; END; ; DELIMITER;
DROP FUNCTION IF EXISTS `mycat_seq_nextval`; DELIMITER; ; CREATE DEFINER = `root`@`%` FUNCTION `mycat_seq_nextval` (seq_name VARCHAR(50)) RETURNS VARCHAR (64) CHARSET latin1 DETERMINISTIC BEGIN UPDATE MYCAT_SEQUENCE SET current_value = current_value + increment WHERE NAME = seq_name; RETURN mycat_seq_currval (seq_name); END; ; DELIMITER;
DROP FUNCTION IF EXISTS `mycat_seq_setval`; DELIMITER; ; CREATE DEFINER = `root`@`%` FUNCTION `mycat_seq_setval` ( seq_name VARCHAR (50), VALUE INTEGER ) RETURNS VARCHAR (64) CHARSET latin1 DETERMINISTIC BEGIN UPDATE MYCAT_SEQUENCE SET current_value = VALUE WHERE NAME = seq_name; RETURN mycat_seq_currval (seq_name); END; ; DELIMITER;
INSERT INTO MYCAT_SEQUENCE(name,current_value,increment,remark) VALUES (‘GLOBAL‘, 1, 100,‘‘); INSERT INTO MYCAT_SEQUENCE(name,current_value,increment,remark) VALUES (‘ORDERS‘, 1, 100,‘订单表使用‘);
select next value for MYCATSEQ_ORDERS
<property name="sequnceHandlerType">2</property>
#sequence depend on TIME WORKID=01 DATAACENTERID=01
<property name="sequnceHandlerType">3</property>
# 代表使用 zk INSTANCEID=ZK # 与 myid.properties 中的 CLUSTERID 设置的值相同 CLUSTERID=010
cd /usr/local/soft/mycat/conf cp *.txt *.xml *.properties zkconf/ chown -R zkconf/ cd /usr/local/soft/mycat/bin ./init_zk_data.sh
原文:https://www.cnblogs.com/47Gamer/p/13664208.html