本地文件方式
此方式 MyCAT 将 sequence 配置到文件中,当使用到 sequence 中的配置后,MyCAT 会更下
classpath 中的 sequence_conf.properties 文件中 sequence 当前的值。
配置
在 sequence_conf.properties 文件中做如下配置:
- GLOBAL_SEQ.HISIDS= GLOBAL_SEQ.MINID=1001
- GLOBAL_SEQ.MAXID=1000000000
- GLOBAL_SEQ.CURID=1000
其中 HISIDS 表示使用过的历史分段(一般无特殊需要可不配置),MINID 表示最小 ID 值,MAXID 表示最大
ID 值,CURID 表示当前 ID 值。
server.xml 配置:
<system><property name="sequnceHandlerType">0</property></system>
数据库方式
在数据库中建立一张表,存放 sequence 名称(name),sequence 当前值(current_value),步长(increment
int 类型每次读取多少个 sequence,假设为 K)等信息。
Sequence 获取步骤:
- 当初次使用该 sequence 时,根据传入的 sequence 名称,从数据库这张表中读取 current_value,和
increment 到 MyCat 中,并将数据库中的 current_value 设置为原 current_value 值+increment 值。 - MyCat 将读取到 current_value+increment 作为本次要使用的 sequence 值,下次使用时,自动加 1,当
使用 increment 次后,执行步骤 1)相同的操作。 - MyCat 负责维护这张表,用到哪些 sequence,只需要在这张表中插入一条记录即可。若某次读取的 sequence 没有用完,系统就停掉了,则这次读取的 sequence 剩余值不会再使用。
配置
server.xml 配置:
<system><property name="sequnceHandlerType">1</property></system>
数据库配置:
-
– 创建存放 sequence 的表
DROP TABLE IF EXISTS MYCAT_SEQUENCE;-
name sequence 名称
-
current_value 当前 value
-
increment 增长步长
mycat 在数据库中一次读取多少个 sequence. 当这些用完后, 下次再从数据库中读取。
CREATE TABLE MYCAT_SEQUENCE ( name VARCHAR(50) NOT NULL, current_value INT NOT NULL, increment INT NOT NULL DEFAULT 100, PRIMARY KEY(name) ) ENGINE=InnoDB; --插入一条 sequence INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES (‘GLOBAL’, 100000, 100);
-
-
创建相关 function
-
获取当前 sequence 的值 (返回当前值,增量)
DROP FUNCTION IF EXISTS mycat_seq_currval; DELIMITER CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf-8 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;
-
设置 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_currval(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 相关配置在哪个节点上
-
本地时间戳方式
ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
换算成十进制为 18 位数的 long 类型,每毫秒可以并发 12 位二进制的累加。
配置
配置 server.xml
<property name="sequnceHandlerType">2</property>
在 mycat 下配置:sequence_time_conf.properties
WORKID=0-31 任意整数
DATAACENTERID=0-31 任意整数
多个个 mycat 节点下每个 mycat 配置的 WORKID,DATAACENTERID 不同,组成唯一标识,总共支持32*32=1024 种组合。
分布式 ZK ID 生成器
<property name="sequnceHandlerType">3</property>
Zk 的连接信息统一在 myid.properties 的 zkURL 属性中配置。
基于 ZK 与本地配置的分布式 ID 生成器(可以通过 ZK 获取集群(机房)唯一 InstanceID,也可以通过配置文
件配置 InstanceID)
ID 结构:long 64 位,ID 最大可占 63 位
配置文件:sequence_distributed_conf.properties,只要配置里面:INSTANCEID=ZK 就是从 ZK 上获取
InstanceID。
Zk 递增方式
<property name="sequnceHandlerType">4</property>
Zk 的连接信息统一在 myid.properties 的 zkURL 属性中配置。
4 是 zookeeper 实现递增序列号
- 配置文件:sequence_conf.properties
- 只要配置好 ZK 地址和表名的如下属性
- TABLE.MINID 某线程当前区间内最小值
- TABLE.MAXID 某线程当前区间内最大值
- TABLE.CURID 某线程当前区间内当前值
- 文件配置的 MAXID 以及 MINID 决定每次取得区间,这个对于每个线程或者进程都有效
- 文件中的这三个属性配置只对第一个进程的第一个线程有效,其他线程和进程会动态读取 ZK
自增长主键
- mysql 本身对非自增长主键,使用 last_insert_id()是不会返回结果的,只会返回 0;
- mysql 只会对定义自增长主键,可以用 last_insert_id()返回主键值,MyCAT 目前提供了自增长主键功能,但是如果对应的 mysql 节点上数据表,没有定义 auto_increment,那么在 MyCAT 层调用 last_insert_id()也是不会返回结果的。
配置
-
mysql 定义自增主键
CREATE TABLE table1( 'id' INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 'name' varchar(32) NOT NULL, PRIMARY KEY ('id') ) ENGINE=MYISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-
mycat 定义主键自增
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> <!-- auto sharding by id (long) --> <table name="user" dataNode="dn1" primaryKey="id"/> <table name="user_consumption_record" dataNode="dn1,dn2,dn3" rule="mod-long" autoIncrement="true" primaryKey="id"/> </schema> <dataNode name="dn1" dataHost="mysql-01" database="db1" /> <dataNode name="dn2" dataHost="mysql-02" database="db2" /> <dataNode name="dn3" dataHost="mysql-03" database="db3" /> <dataHost name="mysql-01" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user()</heartbeat> <writeHost host="host1" url="mysql-01:3306" user="root" password="123456"/> </dataHost> <dataHost name="mysql-02" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user()</heartbeat> <writeHost host="host2" url="mysql-02:3306" user="root" password="123456"/> </dataHost> <dataHost name="mysql-03" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user()</heartbeat> <writeHost host="host3" url="mysql-03:3306" user="root" password="123456"/> </dataHost> </mycat:schema>
-
mycat 对应 sequence_db_conf.properties 增加相应设置
TABLE1=dn1