Mycat——全局序列

全局序列

在实现分库分表的情况下,数据库自增主键已无法保证主键的全局唯一。所以,Mact提供了全区sequence,并且提供了包含本地配置和数据库配置等多种实现方式。

1. 本地文件

原理:此方式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中配置:
sequnceHandlerType需要配置为0,表示使用本地文件方式。

使用示例:


insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);
  • 缺点:当MyCAT重新发布后,配置文件中的sequence会恢复到初始值。
  • 优点:本地加载,读取速度较快。

数据库方式

利用数据库一个表 来进行计数累加。但是并不是每次生成序列都读写数据库,这样效率太低。

Mycat 会预加载一部分号段到 Mycat 的内存中,这样大部分读写序列都是在内存中完成的。 如果内存中的号段用完了 Mycat 会再向数据库要一次。

但是,如果Mycat挂了,Mycat 启动后会向数据库申请新的号段,原有号段会弃用。 也就是说如果 Mycat 重启,那么损失是当前的号段没用完的号码,但是不会因此出现主键重复。

配置:

在dn1数据结点创建MYCAT_SEQUENCE表:

CREATE TABLE MYCAT_SEQUENCE (
	name VARCHAR(50) NOT NULL, #名称
	current_value INT NOT NULL, #当前value
	increment INT NOT NULL DEFAULT 100,  #mycat在数据库中一次读取多少个sequence
	PRIMARY KEY(name)
) ENGINE=InnoDB;

在这里插入图片描述

插入一条sequence:

INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES (‘ORDERS’, 100000, 100);

在这里插入图片描述

创建相关function,返回当前sequence的值:

DROP FUNCTION IF EXISTS mycat_seq_currval;
DELIMITER $$
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS varchar(64)
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) 
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) 
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相关配置在哪个节点上:

例如:
ORDERS=dn1

在这里插入图片描述

配置server.xml:
指定sequenceHandlerType=1,为数据库方式。(0=本地文件、1=数据库、2=时间戳)
在这里插入图片描述

注意:MYCAT_SEQUENCE表和以上的3个function,需要放在同一个节点上。function请直接在具体节点的数据库上执行,如果执行的时候报:

you might want to use the less safe log_bin_trust_function_creators variable
需要对数据库做如下设置:

windows下my.ini[mysqld]加上
log_bin_trust_function_creators=1 

linux下/etc/my.cnf下my.ini[mysqld]加上
log_bin_trust_function_creators=1

修改完后,即可在mysql数据库中执行上面的函数.

测试:登录Mycat,插入数据

insert into orders(id, amount, customer_id, order_type) values(next value for MYCATSEQ_ORDERS, 1000, 101, 102);

insert into orders(id, amount, customer_id, order_type) values(next value for MYCATSEQ_ORDERS, 1000, 101, 103);

在这里插入图片描述
重新Mycat,再次插入数据:
在这里插入图片描述
根据我们的配置,加载到内存的100个序列因为重启被废弃了,重启后mycat重新加载了100个。

时间戳

全局ID = 64位二进制(42(毫秒)+ 5(机器ID)+ 5(机器业务编码)+ 12(重复累加))换算成十进制为18位数的long类型,每毫秒可以并发12位二进制的累加。

优点:配置简单;
缺点:18位ID过长;

自主生成全局序列

  1. 根据业务逻辑组合
  2. 利用redis或zookeeper生成全局ID。
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页