在实现分库分表的情况下,数据库自增主键已经无法保证在集群中是全局唯一的主键了,因此mycat提供了全局的sequence,并且提供了本地配置、数据库配置等多种实现方式。

本地文件方式

采用该方式,mycat将sequence配置到classpath目录的sequence_conf.properties文件中,在sequence_conf.properties文件做如下配置

GLOBAL_SEQ.HISIDS=
GLOBAL_SEQ.MINID=1001
GLOBAL_SEQ.MAXID=100000000
GLOBAL_SEQ.CURID=1000

其中HISIDS表示历史分段(一般无特殊需要则可以不配置),MINID表示最新的ID值,MAXID表示最大的ID值,CURID表示当前的ID值。
需要启用这种方式,则首先需要在servier.xml中配置如下参数:

<system><property name="sequnceHandlerType">0</property></system>

注意:sequnceHandlerType配置为0,表示使用本地文件方式

采用这种方式的缺点是mycat重新发布后,配置文件中的sequence会恢复到初始值,有点事本地加载且读取速度快。

数据库方式

在数据库中创建一张表名为sequence的表,有sequence的当前值(current_value)、步长(increment int 类型,指每次读取多少个sequence,假设值为K)等信息。

squence的获取步骤如下:

1)每次使用sequence时候,根据传入的sequence名称,从数据库表中 读取current_value、increment到mycat中,并将数据库中的current_value 修改为current_value + increment的值。
2)mycat将读取到的current_value+increment 作为本次使用的sequence值,在下次使用的时候,sequence自动加1,当使用increment次后,执行与步骤一相同操作。
3)mycat负责维护这张表,用到哪些sequence时,主需要在这张表插入一条记录即可,若某次读取sequence没有用完就宕机了,则本次已经读取sequence且未使用的值将会被丢弃。

若要启用这种方式,需要在server.xml中配置如下参数:
<system><property name="sequnceHandlerType">1</property></system>

注意:这里配置成1,表示使用数据库方式生成sequence.

数据库配置如下:

创建MYCAT_SEQUENCE的表
CREATE DATABASE `mycat_mobp2p` DEFAULT CHARACTER SET utf8;

use mycat_mobp2p;

CREATE TABLE `MYCAT_SEQUENCE` (
`NAME` varchar(50) NOT NULL,
`current_value` int(11) NOT NULL,
`increment` int(11) NOT NULL DEFAULT '100',
PRIMARY KEY (`NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

name、current_value和increment 分别sequence的名称、当前value的值和增长步长。

插入一条sequence语句:
USER 是已经创建好的逻辑表,已经做好了相关rule

insert into MYCAT_SEQUENCE(name,current_value,increment) VALUES('USER',10000,100);

创建相关的function

DELIMITER $$
USE `mycat_mobp2p`$$
DROP FUNCTION IF EXISTS `mycat_seq_currval`$$
CREATE FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) RETURNS VARCHAR(64) CHARSET utf8
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval="-999999999,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 ;

DELIMITER $$
USE `mycat_mobp2p`$$
DROP FUNCTION IF EXISTS `mycat_seq_nextval`$$
CREATE FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS VARCHAR(64) CHARSET utf8
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END$$
DELIMITER ;

DELIMITER $$
USE `mycat_mobp2p`$$
DROP FUNCTION IF EXISTS `mycat_seq_setval`$$
CREATE FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), VALUE INTEGER) RETURNS VARCHAR(64) CHARSET utf8
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = VALUE
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END$$
DELIMITER ;

equence_db_conf.properties指定 sequence 相关配置在哪个节点上,配置如下:
[root@canal3 conf]# cat sequence_db_conf.properties
GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
ORDERS=dn1
USER=dn2

注意:USER必须为大写,这个与表的数据是否大写无关,事实上,MYCAT_SEQUENCE中name是否大小写对结果没有影响。

[root@canal3 conf]# cat schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="integration01" checkSQLschema="false" sqlMaxLimit="100">
<table name="user" primaryKey="id" autoIncrement="true" subTables="user$1-10" rule="mod-long" dataNode="dn1"></table >
</schema>
<dataNode name="dn1" dataHost="integration01" database="integration01"/>
<dataNode name="dn2" dataHost="mycat_mobp2p" database="mycat_mobp2p"/>

<dataHost name="integration01" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>show slave status</heartbeat>
<writeHost host="10.40.20.44" url="10.40.20.44:3307" user="root" password="chengce243">
<readHost host="10.40.20.44" url="10.40.20.44:3308" user="root" password="chengce243"/>
</writeHost>
</dataHost>

<dataHost name="mycat_mobp2p" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="10.40.20.44" url="10.40.20.44:3307" user="root" password="chengce243">
</writeHost>
</dataHost>

</mycat:schema>

[root@canal3 conf]# cat server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
<property name="useHandshakeV10">1</property>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->

<property name="sequnceHandlerType">1</property>
<property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
<property name="processorBufferPoolType">0</property>
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
<property name="handleDistributedTransactions">0</property>

<!--
off heap for merge/order/group/limit 1开启 0关闭
-->
<property name="useOffHeapForMerge">1</property>

<!--
单位为m
-->
<property name="memoryPageSize">64k</property>

<!--
单位为k
-->
<property name="spillsFileBufferSize">1k</property>

<property name="useStreamOutput">0</property>

<!--
单位为m
-->
<property name="systemReserveMemorySize">384m</property>

<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">false</property>

<!-- XA Recovery Log日志路径 -->
<!--<property name="XARecoveryLogBaseDir">./</property>-->

<!-- XA Recovery Log日志名称 -->
<!--<property name="XARecoveryLogBaseName">tmlog</property>-->

</system>

<!-- 全局SQL防火墙设置 -->
<!--白名单可以使用通配符%或着*-->
<!--例如<host host="127.0.0.*" user="root"/>-->
<!--例如<host host="127.0.*" user="root"/>-->
<!--例如<host host="127.*" user="root"/>-->
<!--例如<host host="1*7.*" user="root"/>-->
<!--这些配置情况下对于127.0.0.1都能以root账户登录-->
<!--
<firewall>
<whitehost>
<host host="1*7.0.0.*" user="root"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->

<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">integration01</property>

<!-- 表级 DML 权限设置 -->
</user>

<user name="user">
<property name="password">user</property>
<property name="schemas">integration01</property>
<property name="readOnly">false</property>
</user>

</mycat:server>

使用示例:
insert into user (borrow_nid,create_user,create_time,update_time) values('201802051008888','dba',now(),now());
insert into user (borrow_nid,create_user,create_time,update_time) values('201802051007777','dba',now(),now());
insert into user (borrow_nid,create_user,create_time,update_time) values('201802051006666','dba',now(),now());
insert into user (borrow_nid,create_user,create_time,update_time) values('201802051005555','dba',now(),now());
insert into user (borrow_nid,create_user,create_time,update_time) values('201802051004444','dba',now(),now());

如果执行时报错:you might want to use the less safe log_bin_trust_function_creators variable。
解决办法:在 my.cnf中设置 SET GLOBAL log_bin_trust_function_creators = 1;

这样做虽然MyCat为无状态而且id有持久化,并且一次可以取出多个id,通过配置可以有主从切换。但是,id还是纯数字,没有有意义的信息,而且,MyCat主从切换并不可靠,id生成有故障,则整个服务都无法正常进行,这在架构上有单点问题,是不推荐的。

sequence配置的更多相关文章

  1. MyCat 主键ID自增长配置

    在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一.为此,MyCat 提供了全局sequence,并且提供了包含本地配置和数据库配置等多种实现方式,实现方式主要有三种:本地文件方式.数 ...

  2. 【转】mybatis 自增主键配置

    mybatis自增主键配置(?) mybatis进行插入操作时,如果表的主键是自增的,针对不同的数据库相应的操作也不同.基本上经常会遇到的就是Oracle Sequece 和 MySQL 自增主键,至 ...

  3. Hibernate配置(通过注解配置)

    本文主要讲通过注解配置来替换Hibernate的映射文件 1.多对一配置 package com.jazz7.entity; import java.util.Date; import javax.p ...

  4. MyCAT全局序列号

    在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一.为此,MyCat 提供了全局sequence,并且提供了包含本地配置和数据库配置等多种实现方式. 本地文件方式 原理:此方式MyCA ...

  5. Mycat 设置全局序列号

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt332 全局序列号介绍 在实现分库分表的情况下,数据库自增主键已无法保证自增主 ...

  6. Mysql主从复制_模式之日志点复制

    MySQL数据复制的原理 MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新.删除等等).因此,要进行复制,必须在主服务器上启用二进制日志. 每个从服务器从主服务器接收主服务器已经记 ...

  7. Mycat配置文件详解及全局序列号

    来详细的看看 mycat的配置文件,更多信息请查看:mycat权威指南. schema.xml: Schema.xml 作为 MyCat 中重要的配置文件之一,管理着 MyCat 的逻辑库.表.分片规 ...

  8. 高可用Mysql架构_Mysql主从复制、Mysql双主热备、Mysql双主双从、Mysql读写分离(Mycat中间件)、Mysql分库分表架构(Mycat中间件)的演变

    [Mysql主从复制]解决的问题数据分布:比如一共150台机器,分别往电信.网通.移动各放50台,这样无论在哪个网络访问都很快.其次按照地域,比如国内国外,北方南方,这样地域性访问解决了.负载均衡:M ...

  9. TDDL实践

    使用入门-数据源配置 数据源配置,tddl的入口,从datasource切入 <bean id="tddlDataSource" class="com.taobao ...

随机推荐

  1. WIN8.1 上安装 debian8.7 遇到的问题及解决方法

    WIN8.1 上安装 debian8.7 遇到的问题及解决方法 参照百度经验 <win7下硬盘安装debian7> ( http://jingyan.baidu.com/article/8 ...

  2. css 兼容性前缀

    一.不同浏览器内核下的书写规则 二:transform  具体变性中心基点  transform-origin  默认情况下  rotate旋转.scale缩放.translate位移.矩阵matri ...

  3. 用C#生成随机中文汉字验证码的基本原理

    前几天去申请免费QQ号码,突然发现申请表单中的验证码内容换成了中文,这叫真叫我大跌眼镜感到好笑,Moper上的猫儿们都大骂腾讯采用中文验证码.^_^  我不得不佩服腾讯为了防止目前网络上横行的QQ号码 ...

  4. 手动挂接NFS

     环境: 单板:s3c2440 内核:Linux-2.6.22.6 U-boot1.16 初始根文件系统Yaffs2 前提条件 1. 开发板上要烧写好文件系统 2. 能正常开机进入Linux系统 3. ...

  5. windows服务插件利器-新生命组件XAgent使用心得

    1.简单介绍 XAgent为大石头带领下的新生命团队自己开发的一个.Net下的常用的Windows服务管理组件利器,通过在控制台中简单的输入1,2,3,4,5等数字可以实现一步安装.卸载Windows ...

  6. HDU 3232 &amp;&amp; UVA 12230 (简单期望)

    Crossing Rivers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. 几种基于Java的SQL解析工具的比较与调用

    1.sqlparser http://www.sqlparser.com/ 优点:支持的数据库最多,除了传统数据库外还支持hive和greenplum一类比较新的数据库,调用比较方便,功能不错 缺点: ...

  8. bootstrap课程7 jquery中结束之前动画用什么

    bootstrap课程7 jquery中结束之前动画用什么 一.总结 一句话总结:stop()方法.$('.navs').not($('.navs').eq(idx)).stop().hide(100 ...

  9. RocketMQ集群消费的那些事

    说明 RocketMQ集群消费的时候,我们经常看到类似注释里面 (1,(2 的写法,已经有时候有同学没注意抛异常的情况就是(3 模拟的情况.那么这3种情况到底是怎么样的呢?你是否都了然于心呢?下面我们 ...

  10. RocketMQ(九):消息发送(续)

    匠心零度 转载请注明原创出处,谢谢! RocketMQ网络部署图 NameServer:在系统中是做命名服务,更新和发现 broker服务. Broker-Master:broker 消息主机服务器. ...