在实现分库分表的情况下,数据库自增主键已经无法保证在集群中是全局唯一的主键了,因此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. OpenStack_Swift源代码分析——ObjectReplicator源代码分析(1)

    1.ObjectorReplicator的启动 首先执行启动脚本 swift-init object-replicator start 此执行脚本的执行过程和ring执行脚本执行过程差点儿相同.找到s ...

  2. 1.24 Python知识进阶 - 类与对象

    类 语法格式: class Dog(object): print("the dog is barking ...") Dog为类名,object为要继承的基类,Dog类会从基类ob ...

  3. Java学习笔记三

    1.面向过程思想,强调的是过程(即动作,函数):面向对象思想,强调的是对象. 2.类与对象关系:类是对事物的描述(属性和行为-方法),对象是类的实例.对象通过new生成.属性也称成员变量;方法也称成员 ...

  4. Quartz学习总结(1)——Spring集成Quartz框架

    一.Quartz简介 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简 ...

  5. mmx-编译脚本

    脚本目录位置 /home/zhangshuli/git2/vanzo_team/xulei/Mmx.py 在-/bin目录下,链接Mmx.py ln -sf ~/git2/vanzo_team/xul ...

  6. Android学习笔记进阶十之Matrix错切变换

    刚开始我也不懂啥叫错切变换,一看效果图你就恍然大悟. 对图像的错切变换做个总结: x = x0 + b*y0; y = d*x0 + y0; 与之对应的方法是: Matrix matrix = new ...

  7. Android: 分页浏览的利器 android View Pager

    最近有一个项目需求,水平滑动实现视图切换(分页显示效果) 最先想到的是ImageSwitcher + ViewFilpper 来实现,这效果做出来我自己都不想用,更不用说客户的感觉了:滑动效果生硬,只 ...

  8. 如何使用echo.js实现图片的懒加载(整理)

    如何使用echo.js实现图片的懒加载(整理) 一.总结 一句话总结:a.在img标签中添加data-echo属性加载真实图片:<img class="loading" sr ...

  9. STL之vector容器的实现框架

    说明:本文仅供学习交流,转载请标明出处,欢迎转载. 实现vector容器的思路等同于实现一个动态数组,以下我们參照源代码的相关资料,给出一个vector容器的大致框架,仅仅有声明,没给出详细的实现. ...

  10. 关于python中矩阵的实现和矩阵的转置

    python中矩阵的实现是靠序列,,, 序列有很多形式, 其实矩阵是现实生活中的东西,把现实生活中的结构转换到程序中. 就需要有个实现的方法,而这种路径是多种多样的. 下面给出一个把矩阵转换成pyth ...