当前位置:   article > 正文

MyCat 分片之枚举规则(多租户)_mycat 多租户 tenant_id

mycat 多租户 tenant_id

myCat的一个重要功能就是数据库分片,允许你将一些规模较大的表分散到不同的数据库,来缓解数据库的压力,或者实现数据的隔离。

当然通过myCat来看,这些分片像是合起来的一张表,只是当sql到达myCat后,根据配置的分片规则,myCat去操作不同的数据库。

没有配置分片规则的表,需要配置为全局表,所有分片的数据是一样的。

如果没有配置分片规则,也没有配置为全局表,那么数据插入时所有分片插入,数据查询时所有分片都查出来,你有几个分片就会查出来几份数据。不过,你可以通过只给这个表配置一个数据节点,来达到既不分片也不全局的目的。

1.MyCat的基础配置

2.编写分片规则

  • 打开conf文件夹下的rule.xml文件,添加以下代码
  1. <!-- 分片规则,按租户分片 -->
  2. <tableRule name="sharding-by-tenant">
  3. <rule>
  4. <columns>tenant_id</columns>
  5. <algorithm>by-tenant</algorithm>
  6. </rule>
  7. </tableRule>
  8. <!-- 分片方法,按照sharding-by-tenant.txt文件进行枚举分片 -->
  9. <!-- type为分片字段的数据类型,1为字符串,0为int -->
  10. <!-- defaultNode配置是否使用默认节点,默认为0,表示不设置默认节点,这样会导致遇到不识别的枚举值时会报错,如果设置的值大于零,该值就是默认节点,会把不识别的枚举值分配到默认节点。 -->
  11. <function name="by-tenant" class="io.mycat.route.function.PartitionByFileMap">
  12. <property name="mapFile">sharding-by-tenant.txt</property>
  13. <property name="type">1</property>
  14. <property name="defaultNode">0</property>
  15. </function>

注意:mycat的配置文件,节点的顺序是有要求的,所有的tableRule要放在前面,所有的function要放在后面

  • conf文件夹下创建sharding-by-tenant.txt文件,内容如下
  1. 220=0
  2. 30=1

意思是tenant_id字段值为220时,走第一个dataNode,值为30时,走第二个dataNode。找不到对应分片时,默认走第一个。

3.给表配置分片规则

  • 打开schema.xml文件,为table配置分片规则
  1. <?xml version="1.0"?>
  2. <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
  3. <mycat:schema xmlns:mycat="http://io.mycat/">
  4. <schema name="demo_db" checkSQLschema="false" sqlMaxLimit="100">
  5. <table name="sys_user" primaryKey="id" rule="sharding-by-tenant" dataNode="dn1,dn2" />
  6. </schema>
  7. <dataNode name="dn1" dataHost="dataHost220" database="demo_db" />
  8. <dataNode name="dn2" dataHost="dataHost30" database="demo_db" />
  9. <dataHost name="dataHost220" maxCon="1000" minCon="10" balance="3"
  10. writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
  11. <heartbeat>select user()</heartbeat>
  12. <writeHost host="hostM1" url="192.168.3.220:3306" user="root" password="root">
  13. <readHost host="hostS2" url="192.168.3.220:3307" user="root" password="root" />
  14. </writeHost>
  15. </dataHost>
  16. <dataHost name="dataHost30" maxCon="1000" minCon="10" balance="3"
  17. writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
  18. <heartbeat>select user()</heartbeat>
  19. <writeHost host="hostM1" url="192.168.3.30:3306" user="root" password="Root@123">
  20. <readHost host="hostS2" url="192.168.3.30:3307" user="root" password="Root@123" />
  21. </writeHost>
  22. </dataHost>
  23. </mycat:schema>

4.测试分片

mycat的枚举分片,根据分片字段,来进行分片的,分片字段不能修改。

插入一条数据时,根据分片字段会将其插入相应的分片数据库。

查询数据时,如果查询语句的where语句中包含分片字段,则只会去查询相应的分片数据库(没有匹配的枚举型会查默认节点),否则全部节点都查询。

可以根据以上特性,测试分片是否成功。现在tenant_id=220存在dataNode1,tenant_id=30存在dataNode2,如果向dataNode1中插入一条tenant_id=30的数据。通过mycat查询,带上条件为tenant_id=30,应该是查不到刚才的数据的。

5.分布式自增长主键问题

像这样进行分片,每个分片都进行自增长主键,那么在mycat中就会发生主键冲突,那么最好有一个分布式的统一主键管理。

mycat也提供了多种的分布式自增长主键方式,我选择了我认为最合适的一种。

  • 在dn1的主库中,创建一个序列表。

像这个配置,mycat在启动时,会自动从表中,读取100条ID,用完了,再去读100条。这样即使你有多个mycat负载均衡,也不会出现主键冲突。

  1. #所有操作都在 db1 上
  2. #创建 MYCAT_SEQUENCE 表
  3. DROP TABLE IF EXISTS MYCAT_SEQUENCE;
  4. – name sequence 名称
  5. – current_value 当前 value
  6. – increment 增长步长! mycat在数据库中一次读取多少个sequence
  7. CREATE TABLE MYCAT_SEQUENCE (name VARCHAR(50) NOT NULL,current_value INT
  8. NOT NULL,increment INT NOT NULL DEFAULT 100, PRIMARY KEY(name))
  9. ENGINE=InnoDB;
  10. #插入一条 sequence
  11. INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES (‘SYS_USER’,
  12. 100, 100);

注意:表名MYCAT_SEQUENCE必须是大写。

注意:在dn1节点的从库的配置文件my.cnf中,添加以下代码,来忽略对序列表的同步。

replicate-ignore-table = demo_db.MYCAT_SEQUENCE
  • 在dn1的主库中,创建必须的方法
  1. CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8
  2. BEGIN
  3. DECLARE retval VARCHAR(64);
  4. SET retval='-999999999,NULL';
  5. SELECT CONCAT(CAST(current_value AS CHAR),',',CAST(increment AS CHAR)) INTO retval FROM
  6. MYCAT_SEQUENCE WHERE NAME = seq_name;
  7. RETURN retval;
  8. END
  1. CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8
  2. BEGIN
  3. UPDATE MYCAT_SEQUENCE SET current_value = current_value + increment WHERE NAME = seq_name;
  4. RETURN mycat_seq_currval(seq_name);
  5. END
  1. CREATE DEFINER=`root`@`%` FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50),VALUE INTEGER) RETURNS varchar(64) CHARSET utf8
  2. BEGIN
  3. UPDATE MYCAT_SEQUENCE SET current_value = VALUE WHERE NAME = seq_name;
  4. RETURN mycat_seq_currval(seq_name);
  5. END
  • 在mycat的配置文件sequence_db_conf.properties中,添加以下代码
SYS_USER=dn1

这个“SYS_USER”即是序列表中name列的内容,也是表名。

  • 在mycat的配置文件schema.xml中,为表SYS_USER添加自增长配置
  1. <schema name="demo_db" checkSQLschema="false" sqlMaxLimit="100">
  2. <table name="sys_user" primaryKey="id" rule="sharding-by-tenant" autoIncrement="true" dataNode="dn1,dn2" />
  3. </schema>
  • 确保mycat的配置文件server.xml中,这一项值为1
<property name="sequnceHandlerType">1</property>

配置完成。

如果mycat启动不成功,请查看mycat/logs/wrapper.log日志

如果mycat启动后出现问题,或者功能出现问题,清查看mycat/logs/mycat.log日志

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/407407?site
推荐阅读
相关标签
  

闽ICP备14008679号