在前面的文章中,已经说过分库分表需要应对的技术难题有如下几个:
1. 分布式全局唯一id
2. 分片规则和策略
3. 跨分片技术问题
4. 跨分片事物问题
下面我们来看一下Mycat是如何解决分布式全局唯一id的问题的
二、Mycat全局序列号Mycat保证id唯一的方式有如下几个:
1)本地文件方式
2)数据库方式
3)时间戳方式
4)ZKID生成器
5)ZK递增ID
4,5
1)sequnceHandlerType进行相应全局序列号策略选项设置(server.xml),在mycat中对应的源码是MyCATSequnceProcessor.java
0sequnceHandlerType可取的值有以下几个:
0:本地文件方式 1:数据库方式 2:时间戳方式 3:ZKID生成器 4:ZK递增ID
2)autoIncrement属性为true(schema.xml)
1. 本地文件方式使用到的mycat源码:io.mycat.route.sequence.handler.IncrSequenceHandler
在server.xml文件中开启全局序列号的配置:
0使用到的配置文件:sequence_conf.properties
COMPANY.HISIDS=COMPANY.MINID=1001
COMPANY.MAXID=2000
COMPANY.CURID=1000
CUSTOMER.HISIDS=
CUSTOMER.MINID=1001
CUSTOMER.MAXID=2000
CUSTOMER.CURID=1000
ORDER.HISIDS=
ORDER.MINID=1001
ORDER.MAXID=2000
ORDER.CURID=1000
HOTNEWS.HISIDS=
HOTNEWS.MINID=1001
HOTNEWS.MAXID=2000
HOTNEWS.CURID=1000
拿HOTNEWS这个表的配置来说明:
示例:
1.1 在mycat的schema.xml文件里面分别配置逻辑表hotnews和mysql的主从机,注意autoIncrement="true"才能使用全局唯一id select user() 1.2 在主数据库(192.168.152.130)分别创建3个数据库db1,db2,db3,然后创建hotnews表 () () );<span >create <span >database<span > db2;
<span >use<span > db2;
<span >create <span >table<span > hotnews(
id <span >bigint(<span >20) <span >not <span >null <span >primary <span >key<span > auto_increment,title <span >varchar(<span >50) <span >default <span >null<span >
);
<span >use<span > db3;
<span >create <span >table<span > hotnews(
id <span >bigint(<span >20) <span >not <span >null <span >primary <span >key<span > auto_increment,title <span >varchar(<span >50) <span >default <span >null<span >
);
1.3 插入数据插入数据到hotnews前我们先来看一下使用本地文件方式的配置文件sequence_conf.properties的内容
cat sequence_conf.properties grep HOTNEWS插入数据到hotnews
hotnews(id,title) ( value MYCATSEQ_HOTNEWS, hotnews(id, hotnews(id,);1.4 查看hotnews表的结果 hotnews;再次查看配置文件sequence_conf.properties的内容,发现内容随着插入数据的自增id做了改变
2. 数据库方式使用到的mycat源码:io.mycat.route.sequence.handler.IncrSequenceMySQLHandler
这里还是以hotnews表为例
2.1 在server.xml文件中开启全局序列号的配置:1使用到的配置文件:sequence_db_conf.properties
vim sequence_db_conf.properties#sequence stored dn1
2.2 选择其中的一个分片,执行如下步骤,譬如我在dn1中创建,对应的数据库名为db1(为什么这里会涉及到datanode,因为后续的sequence_db_conf.properties文件会使用到),
第一步:创建SEQUENCE表,用来存储序列号
() , , , INNODB ; INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('GLOBAL',100000,100);第二步:创建SEQ function
`mycat_seq_currval`(seq_name ( ( retval ( retval", concat((current_value ),",(increment ) ) MYCAT_SEQUENCE name <span >--<span > 获取下一个sequence值<span >DROP <span >FUNCTION <span >IF <span >EXISTS<span >
mycat_seq_nextval
;DELIMITER ;;
<span >CREATE <span >FUNCTION
mycat_seq_nextval
(seq_name <span >VARCHAR(<span >50)) <span >RETURNS <span >varchar(<span >64<span >)CHARSET utf8
DETERMINISTIC
<span >BEGIN <span >UPDATE<span > MYCAT_SEQUENCE
<span >SET current_value <span >= current_value <span >+<span > increment
<span >WHERE name <span >=<span > seq_name;
<span >RETURN<span > mycat_seq_currval(seq_name);
<span >END<span >
;;
DELIMITER ;<span >--<span > 设置sequence值
<span >DROP <span >FUNCTION <span >IF <span >EXISTS<span >
mycat_seq_setval
;DELIMITER ;;
<span >CREATE <span >FUNCTION
mycat_seq_setval
(seq_name <span >VARCHAR(<span >50),value <span >INTEGER<span >)<span >RETURNS <span >varchar(<span >64<span >) CHARSET utf8
DETERMINISTIC
<span >BEGIN <span >UPDATE<span > MYCAT_SEQUENCE
<span >SET current_value <span >=<span > value
<span >WHERE name <span >=<span > seq_name;
<span >RETURN<span > mycat_seq_currval(seq_name);
<span >END<span >
;;
DELIMITER ;
插入需要自增长的表的策略,这条数据是我们hotnews这个表所需要的。 name必须是大写的字符,不然就会报错
MYCAT_SEQUENCE (,,);第三步:在sequence_db_conf.properties这个文件中定义hotnews这张表的序列名称,同时可以定义到哪个分片上。这里是定义在dn1上的
名字=分片1[,分片2][,.....][,分片N]
vim sequence_db_conf.properties
保存:
:wq
2.3 重启mycat# .binmycat restart;2.4 连接mycat进行数据测试mysql uroot p123456 P8066 h192..插入数据
hotnews(id, hotnews(id, hotnews(id,);查看结果:
hotnews;3. 本地时间戳方式
使用到的mycat源码:io.mycat.route.sequence.handler.IncrSequenceTimeHandler
3.1 在server.xml文件中开启全局序列号的配置:2使用到的配置文件:
sequence_time_conf.properties
WORKID=01(范围01-31)
DATAACENTERID=01(范围01-31)
示例:
首先清空hotnews这张表的数据,方便查看测试结果
hotnews;插入测试数据
hotnews(id,title) ( value MYCATSEQ_GLOBAL, hotnews(id, hotnews(id,);查看结果:
hotnews;4. 自增长主键
方式1:不同自增长初始值+相同步长
方式2:参考“数据库方式”
5. 分布式ZK ID生成环境准备:先在虚拟机192.168.152.130里面装好zookeeper,具体参考我的文章
5.1 在server.xml文件中开启全局序列号的配置:vim server.xml
35.2 修改如下配置文件:1)myID.propertIEs
vim myID.propertIEsloadZK=true|false //
zkURL=xxx.xxx.xxx.xxx:2182,xxx.xxx.xxx.xxx:2182,xxx.xxx.xxx.xxx:2182
clusterID=
2)sequence_distributed_conf.propertIEs
vim sequence_distributed_conf.propertIEsINSTANCEID=ZK //
CLUSTERID=01 //集群
5.3 重启mycat# .binmycat restart;5.4 连接mycat进行数据测试MysqL -uroot -p123456 -P8066 -h192.168.152.128插入数据
hotnews(ID, hotnews(ID, hotnews(ID,