赞
踩
myCat的一个重要功能就是数据库分片,允许你将一些规模较大的表分散到不同的数据库,来缓解数据库的压力,或者实现数据的隔离。
当然通过myCat来看,这些分片像是合起来的一张表,只是当sql到达myCat后,根据配置的分片规则,myCat去操作不同的数据库。
没有配置分片规则的表,需要配置为全局表,所有分片的数据是一样的。
如果没有配置分片规则,也没有配置为全局表,那么数据插入时所有分片插入,数据查询时所有分片都查出来,你有几个分片就会查出来几份数据。不过,你可以通过只给这个表配置一个数据节点,来达到既不分片也不全局的目的。
- <!-- 分片规则,按租户分片 -->
- <tableRule name="sharding-by-tenant">
- <rule>
- <columns>tenant_id</columns>
- <algorithm>by-tenant</algorithm>
- </rule>
- </tableRule>
-
-
-
- <!-- 分片方法,按照sharding-by-tenant.txt文件进行枚举分片 -->
- <!-- type为分片字段的数据类型,1为字符串,0为int -->
- <!-- defaultNode配置是否使用默认节点,默认为0,表示不设置默认节点,这样会导致遇到不识别的枚举值时会报错,如果设置的值大于零,该值就是默认节点,会把不识别的枚举值分配到默认节点。 -->
- <function name="by-tenant" class="io.mycat.route.function.PartitionByFileMap">
- <property name="mapFile">sharding-by-tenant.txt</property>
- <property name="type">1</property>
- <property name="defaultNode">0</property>
- </function>
注意:mycat的配置文件,节点的顺序是有要求的,所有的tableRule要放在前面,所有的function要放在后面
- 220=0
- 30=1
意思是tenant_id字段值为220时,走第一个dataNode,值为30时,走第二个dataNode。找不到对应分片时,默认走第一个。
- <?xml version="1.0"?>
- <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
- <mycat:schema xmlns:mycat="http://io.mycat/">
- <schema name="demo_db" checkSQLschema="false" sqlMaxLimit="100">
- <table name="sys_user" primaryKey="id" rule="sharding-by-tenant" dataNode="dn1,dn2" />
- </schema>
-
- <dataNode name="dn1" dataHost="dataHost220" database="demo_db" />
- <dataNode name="dn2" dataHost="dataHost30" database="demo_db" />
- <dataHost name="dataHost220" maxCon="1000" minCon="10" balance="3"
- writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
- <heartbeat>select user()</heartbeat>
- <writeHost host="hostM1" url="192.168.3.220:3306" user="root" password="root">
- <readHost host="hostS2" url="192.168.3.220:3307" user="root" password="root" />
- </writeHost>
- </dataHost>
- <dataHost name="dataHost30" maxCon="1000" minCon="10" balance="3"
- writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
- <heartbeat>select user()</heartbeat>
- <writeHost host="hostM1" url="192.168.3.30:3306" user="root" password="Root@123">
- <readHost host="hostS2" url="192.168.3.30:3307" user="root" password="Root@123" />
- </writeHost>
- </dataHost>
-
- </mycat:schema>
mycat的枚举分片,根据分片字段,来进行分片的,分片字段不能修改。
插入一条数据时,根据分片字段会将其插入相应的分片数据库。
查询数据时,如果查询语句的where语句中包含分片字段,则只会去查询相应的分片数据库(没有匹配的枚举型会查默认节点),否则全部节点都查询。
可以根据以上特性,测试分片是否成功。现在tenant_id=220存在dataNode1,tenant_id=30存在dataNode2,如果向dataNode1中插入一条tenant_id=30的数据。通过mycat查询,带上条件为tenant_id=30,应该是查不到刚才的数据的。
像这样进行分片,每个分片都进行自增长主键,那么在mycat中就会发生主键冲突,那么最好有一个分布式的统一主键管理。
mycat也提供了多种的分布式自增长主键方式,我选择了我认为最合适的一种。
像这个配置,mycat在启动时,会自动从表中,读取100条ID,用完了,再去读100条。这样即使你有多个mycat负载均衡,也不会出现主键冲突。
- #所有操作都在 db1 上
- #创建 MYCAT_SEQUENCE 表
- DROP TABLE IF EXISTS MYCAT_SEQUENCE;
- – name sequence 名称
- – current_value 当前 value
- – increment 增长步长! mycat在数据库中一次读取多少个sequence
-
- CREATE TABLE MYCAT_SEQUENCE (name VARCHAR(50) NOT NULL,current_value INT
- NOT NULL,increment INT NOT NULL DEFAULT 100, PRIMARY KEY(name))
- ENGINE=InnoDB;
-
- #插入一条 sequence
- INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES (‘SYS_USER’,
- 100, 100);
注意:表名MYCAT_SEQUENCE必须是大写。
注意:在dn1节点的从库的配置文件my.cnf中,添加以下代码,来忽略对序列表的同步。
replicate-ignore-table = demo_db.MYCAT_SEQUENCE
- CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8
- 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
- CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8
- BEGIN
- UPDATE MYCAT_SEQUENCE SET current_value = current_value + increment WHERE NAME = seq_name;
- RETURN mycat_seq_currval(seq_name);
- END
- CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50),VALUE INTEGER) RETURNS varchar(64) CHARSET utf8
- BEGIN
- UPDATE MYCAT_SEQUENCE SET current_value = VALUE WHERE NAME = seq_name;
- RETURN mycat_seq_currval(seq_name);
- END
SYS_USER=dn1
这个“SYS_USER”即是序列表中name列的内容,也是表名。
- <schema name="demo_db" checkSQLschema="false" sqlMaxLimit="100">
- <table name="sys_user" primaryKey="id" rule="sharding-by-tenant" autoIncrement="true" dataNode="dn1,dn2" />
- </schema>
<property name="sequnceHandlerType">1</property>
配置完成。
如果mycat启动不成功,请查看mycat/logs/wrapper.log日志
如果mycat启动后出现问题,或者功能出现问题,清查看mycat/logs/mycat.log日志
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。