Mycat全局Sequence详解

#Mycat全局Sequence详解 在分布数数据库设计环节,将一个大表切分成各个子表,并且存储到各个数据节点上,如何保持一条数据记录的全局唯一性是一个关键性问题。mycat提供了一种全局sequence的机制,并且提供了多种实现方案。该文将对Mycat这一块进行讨论,以理清mycat这一块的设计思路。

mycat当前提供了master分支提供了三种全局sequence实现方式,还有一种zookeeper好像还处于开发阶段,没有看到完整的实现代码。下面将对这三种实现方式进行讨论。

##从哪里配置采用那种全局Sequence实现 在SystemConfig中有如下几行代码:

<!--lang:java-->
public static final int SEQUENCEHANDLER_LOCALFILE = 0;
public static final int SEQUENCEHANDLER_MYSQLDB = 1;
public static final int SEQUENCEHANDLER_LOCAL_TIME = 2;
private int sequnceHandlerType = SEQUENCEHANDLER_LOCALFILE;

这里可以看到提供了三种实现方式。看到上面,如果熟悉mycat的话就应该知道在哪里配置sequnceHandlerType参数了。如果不熟悉也没关系,下面我告诉大家,在mycat的conf/server.xml的<system>标签内添加<property name="sequnceHandlerType">1/0/2</property>,在<system>标签内的所有<property>标签都会通过name属性找到SystemConfig中的属性并且自动将配置的值赋予到对应的属性中去(这部分实现可以看看XMLServerLoaderloadSystem实现)。

mycat对于sequence生成策略抽象出了一个接口-SequenceHandler,这个接口提供的实现类有IncrSequenceMySQLHandler,IncrSequencePropHandler,IncrSequenceTimeHandlerIncrSequenceZKHandler,其中IncrSequenceZKHandler还没有具体的实现。通过类名应该知道了具体哪个类实现了哪个sequence策略类型。比如SEQUENCEHANDLER_LOCALFILE策略是IncrSequencePropHandler实现类,SEQUENCEHANDLER_MYSQLDB策略是IncrSequenceMySQLHandler实现类,SEQUENCEHANDLER_LOCAL_TIMEIncrSequenceTimeHandler实现类。说到这里感觉mycat对于插件化这一块做的不够好,比如这里的sequence策略实现,完全可以插件化,但是从mycat加载各个具体实现的地方,都是通过硬编码去获取具体实现,而没有提供一种外部去接入的地方,所以如果外部需要实现自己的sequence策略,只能修改源码,这方面感觉还不够开放,例如下面硬编码获取具体实现:

<!--lang:java-->
public DruidSequenceHandler(int seqHandlerType) {
	switch(seqHandlerType){
	case SystemConfig.SEQUENCEHANDLER_MYSQLDB:
		sequenceHandler = IncrSequenceMySQLHandler.getInstance();
		break;
	case SystemConfig.SEQUENCEHANDLER_LOCALFILE:
		sequenceHandler = IncrSequencePropHandler.getInstance();
		break;
	case SystemConfig.SEQUENCEHANDLER_LOCAL_TIME:
		sequenceHandler = IncrSequenceTimeHandler.getInstance();
		break;
	default:
		throw new java.lang.IllegalArgumentException("Invalid sequnce handler type "+seqHandlerType);
	}
}

上面配置完值,如何在插入的时候从sequence获取值呢?这方面mycat提供了一种规范,通过“next value for MYCATSEQ_SEQUENCENAME”方式获取下一个sequence值。 比如insert into t_users (id,province_code) values(next value for MYCATSEQ_USERS,"110000");,t_user的id属性mycat会自动从全局USERS sequence中获取一个值。

上面列出了mycat在sequence策略方面的三个具体实现(其中zk还没有实现完,所以是三个),那么下面将对这三个实现进行介绍。

##SEQUENCEHANDLER_LOCALFILE(0) 这种方式的实现是通过IncrSequencePropHandler类去实现,也是mycat提供默认的实现方式。通过静态配置文件来设置全局sequence的取值范围。各个全局sequence的配置放在sequence_conf.properties文件中,格式如下:

<!--lang:java-->
#default global sequence
GLOBAL.HISIDS= //GLOBAL sequence历史的分片区间
GLOBAL.MINID=10001	//GLOBAL sequence 当前获取的最小值
GLOBAL.MAXID=20000	//GLOBAL sequence 当前能够获取的最大id
GLOBAL.CURID=10000 //GLOBAL sequence 当前的值

其中GLOBAL就是sequence的名称,比如你创建一个USER的sequence,就如下进行创建:

<!--lang:java-->
#default user sequence
USER.HISIDS= //USER sequence历史的分片区间
USER.MINID=10001	//USER sequence 当前获取的最小值
USER.MAXID=20000	//USER sequence 当前能够获取的最大id
USER.CURID=10000 //USER sequence 当前的值

mycat每次从sequence_conf.properties获取一个sequence之后将会把CURID跟新到sequence_conf.properties文件中,并且如果当前的CURID大于MAXID,则会自动扩容,并且扩容的区间范围是和设置的范围一样。

##SEQUENCEHANDLER_MYSQLDB(1) 这种方式是将sequence信息存储在数据库中,并且在对应数据库中执行响应的存储过程,然后mycat会调用对应的存储过程获取对赢的sequence,存储过程可以从这里获取。这部分在Mycat里面的具体实现是在IncrSequenceMySQLHandler中。在使用这个进行存储和获取sequence的时候,需要配置sequence的表是在哪个数据节点上,这些信息是配置在conf/sequence_db_conf.properties文件中。格式如下:

<!--lang:java-->
#sequence stored in datanode
GLOBAL=sequence //sequence名称=数据节点名称(配置在schema.xml里面)
USERS=sequence
ORDERS=sequence

##SEQUENCEHANDLER_LOCAL_TIME(2) 这种方式有点类似采用UUID的方式来生成一个全局的唯一标识,这种规则的实现实在唉IncrSequenceTimeHandler中。需要配置conf/sequence_time_conf.properties文件。格式如下: <!--lang:java--> #sequence depend on TIME WORKID=01 DATAACENTERID=01

转载于:https://my.oschina.net/bieber/blog/508735

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值