0%

分布式全局序列

分布式全局序列

由于Mycat进行分表操作,为了保证整个表的不同分片中的id要全局唯一,不可以使用mysql的自增id,那么如何进行全局序列的生成?

Mycat提供了三种生成全局序列的方式,本地文件、数据库方式、时间戳方式

在server.xml中配置sequnceHandlerType

1
2
<!-- 指定使用Mycat全局序列的类型。0为本地文件方式,1为数据库方式,2为时间戳序列方式 -->
<property name="sequnceHandlerType">1</property>

本地文件

Mycat将序列号配置到文件中,当使用序列号中的配置后,Mycat会更新classpath中sequence_conf.properties文件中sequence当前的值

1
2
3
4
GLOBAL_SEQ.HISIDS=   #表示使用过的历史分段
GLOBAL_SEQ.MINID=1 #表示最小ID值
GLOBAL_SEQ.MAXID=10000000 #表示最大ID值
GLOBAL_SEQ.CURID=1000 #表示当前ID值

使用方式

1
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);

如果mycat所在主机宕机后,无法读取本地文件。重启之后配置文件的sequence会恢复到初始值

数据库方式

利用数据库一个表来进行计数累加,Mycat会预加载一部分号段到Mycat的内存中,使得大部分读写序列都在内存中完成,如果内存中的号段用完了则Mycat会向数据库再次要一遍

表结构:name 名称、current_value 当前值、increment 增长步长(一次读取多少个sequence,当这些用完后,再从数据库中读取)

创建相关function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
-- 获取当前sequence的值
drop function if exists mycat_seq_curval;
delimiter $
create function mycat_seq_curval(seq_name varchar(50)) returns varchar(64) charset utf-8
deterministic
begin
declare retval varchar(64);
set reval= "-99999999,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;


-- 设置sequence值
drop function if exists mycat_seq_setval;
delimiter $
create function mycat_seq_setval(seq_name varchar(50),value integer) returns varchar(64) charset utf-8
deterministic
begin
update mycat_sequence
set current_value=value
where name = seq_name;
return mycat_seq_curval(seq_name);
end $
delimiter;

-- 获取下一个sequence值
drop function if exists mycat_seq_nextval;
delimiter $
create function mycat_seq_nextval(seq_name varchar(50)) returns varchar(64) charset utf-8
deterministic
begin
update mycat_sequence set current_value = current_value+increment where name = seq_name;
return mycat_seq_currval(seq_name);
end $
delimiter;

然后在sequence_db_conf.properties配置中指定sequence配置在哪个节点上

1
USER_SEQ=dn1

时间戳方式

64位二进制(42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))换算成十进制18位数的long类型

在sequence_distributed_conf.properties中配置对应的WORKID和DATAACENTERID

1
2
3
4
#sequence depend on TIME
# 多个节点配置不同的WORKID、DATAACENTERID,这样使得生成的id不会重复
WORKID=01
DATAACENTERID=01

欢迎关注我的其它发布渠道