Mycat全局Sequence详解

Stella981
• 阅读 675

#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的标签内添加<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文件。格式如下: #sequence depend on TIME WORKID=01 DATAACENTERID=01

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
mysql主从之基于mycat实现读写分离
一环境  1.1结构192.168.132.125mycat192.168.132.121 master192.168.132.122 slave主从已经配置完成1.2安装mycat192.168.132.125安装mycat\root@mycat~\  cd/usr/lo
Stella981 Stella981
3年前
MyCat性能优化
  由于公司业务的快速发展导致数据库的数据量飞速增长,我们底层数据的存储,逐渐成为制约整个产品性能的核心部分。于是我们调研了各大数据库分库产品,如:hibernate5对多租户的支持,当当ShardingJdbc,mysqlProxy,mycat等。最终考虑到国内目前各个产品的活跃度和成熟度,以及对现有业务的适配情况,最终选择了mycat作为分库分表的
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Mycat
Mycat介绍,请戳官网:http://www.mycat.io/官网地址:http://dl.mycat.io/1.6.5/以oracle物理库为例。1、解压安装包tarzxvfMycatserver1.6.5release20171029183033linux.tar.gz!(https:/
Wesley13 Wesley13
3年前
mysql 未定义主键,mysql 如何处理?
InnoDB会自动帮你创建一个不可见的、长度为6字节的row\_id,而且InnoDB维护了一个全局的dictsys.row\_id,所以未定义主键的表都会共享该row\_id,每次插入一条数据都把全局row\_id当成主键id,然后全局row\_id加1。该全局row\_id在代码实现上使用的事bigintunsigned类型,但实际上只给row\_
Stella981 Stella981
3年前
Mycat适配oracle,各种坑
注:文中使用版本为Mycat1.6.5。1、Mycat正如官方所说,Mycat是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。由于前面讲的对数据进行分片处理之后,从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储。当然,Mycat没有自己的存储引擎,并
Stella981 Stella981
3年前
MyCat业务上规避跨库Join实现方式
全局表如果你的业务中有些数据类似于数据字典,比如配置文件的配置,常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大,而且大部分的业务场景都会用到,那么这种表适合于Mycat全局表,无须对数据进行切分,只要在所有的分片上保存一份数据即可,Mycat在Join操作中,业务表与全局表进行Join聚合会优先选择相同分片内的全局表jo
Wesley13 Wesley13
3年前
MySQL 部署分布式架构 MyCAT (五)
分片(水平拆分)4.全局表业务使用场景:如果你的业务中有些数据类似于数据字典,比如配置文件的配置,常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大,而且大部分的业务场景都会用到,那么这种表适合于Mycat全局表,无须对数据进行切分,要在所有的分片上保存一份数据即可
Stella981 Stella981
3年前
Mycat的配置(一)
   Schema.xml作为Mycat中最重要的配置文件之一,管理着Mycat的逻辑库、表、分片规则、DataNode以及DataSource。1.Schema标签<schemaname"TESTDB"checkSQLschema"false"sqlMaxLimit"100"</sch
Stella981 Stella981
3年前
Mycat 分布式事务的实现
Mycat分布式事务的实现博客分类:java数据库引言:Mycat已经成为了一个强大的开源分布式数据库中间件产品。面对企业应用的海量数据事务处理,是目前最好的开源解决方案。但是如果想让多台机器中的数据保存一致,比较常规的解决方法是引入“协调者”来统一调度所有节点的执行。 本文选自《分布式数据库架构及企业实践——基于Mycat中间件》