介绍

Mycat的前身是阿里巴巴大名鼎鼎的Cobar,Cobar在开源了一段时间后,就没有再维护了,阿里巴巴放弃了该项目,再加上Cobar在使用过程中也发现存在一些问题。

2013年国内一批开源软件爱好者对Cobar这个项目进行了改进,并命名为Mycat,这就是MyCat的诞生。

MyCat是完全免费开源的,不属于任何商业公司。

权威指南:https://www.yuque.com/books/share/0576de75-ffc4-4c34-8586-952ae4636944

Mycat是一个开源数据库中间件,是一个实现了MySQL协议的的数据库中间件服务器,我们可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问Mycat,而Mycat再使用MySQL原生(Native)协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,包括SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储;

一般地,Mycat主要用于代理MySQL数据库,虽然它也支持去访问其他类型的数据库;

Mycat的默认端口是8066,一般地,我们可以使用常见的对象映射框架比如MyBatis操作Mycat。

主要能做什么

  • 负载均衡

  • 数据库的读写分离
    如果有了Mycat,客户端直接连接Mycat,可以实现读写分离,如果主出现问题,会自动切换到从服务器上

  • 数据库分库分表
    水平切分(横向切分)
    根据表中数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库服务器上面

    垂直切分(纵向切分)
    按照不同的表来切分到不同的数据库服务器之上

性能有瓶颈了,可以读写分离
数据库容量有瓶颈了,可以分库分表

安装

下载
http://dl.mycat.org.cn/

解压后切换到mycat的bin路径下,执行
启动Mycat服务:./mycat start
关闭Mycat服务:./mycat stop
启动后要观察下有没有要运行,错误地运行会掉服务sp -ef | grep mycat

运行Mycat(以Mysql方式运行)
./mysql -umycat -p -P8066 -h127.0.0.1

主要修改的配置文件

注意!!文件格式编码为UTF-8

rule.xml

水平分表的时候用到
在原有的rule的xml文件中,设置节点配置的数量

server.xml

主要用于配置mycat需要的服务器信息

Ø 配置序列生成方式

Ø 配置mycat逻辑数据库

Ø 配置mycat的访问账户和密码

sequnceHandlerType属性

指定使用Mycat全局序列的类型:

0为本地文件方式,1为数据库方式,2为时间戳序列方式
对于读写分离而言,是不需要考虑主键生成方式的,也就是不需要配置全局序列号的。

user属性

创建一个用户,使用此用户,登录mysql时需要用到

schema.xml

用于配置的逻辑数据库的映射、表、分片规则、数据结点及真实的数据库信息;

Ø 配置逻辑库映射

Ø 配置垂直切分的表

Ø 配置真实的数据库

Ø 配置读写结点

配置dataNode

dataNode定义了Mycat中的数据节点,也就是我们通常说所的数据分片。
一个dataNode标签就是一个独立的数据分片,通俗理解,一个分片就是一个物理数据库

Ø name
定义数据节点的名字,这个名字需要是唯一的,这个名字在schema里面会使用到;

Ø dataHost
用于定义该分片属于哪个数据库实例的,属性值是引用dataHost标签上定义的name属性

Ø database
用于对应真实的数据库名,必须是真实存在的;

配置dataHost

定义具体的数据库实例、读写分离配置和心跳语句;

  • Ø balance属性
    负载均衡类型,目前的取值有4种:
    n balance=”0”, 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上;
    n balance=”1”,全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
    n balance=”2”,所有读操作都随机的在writeHost、readhost上分发
    n balance=”3”,所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力

  • Ø switchType属性
    用于指定主服务器发生故障后的切换类型
    -1 表示不自动切换
    1 默认值,自动切换(推荐)
    2 基于MySQL主从同步的状态决定是否切换
    3 基于MySQL galary cluster的切换机制(适合集群)(1.4.1)
    通常情况下,我们MySQL采用双主双从的模式下,switchType为1即可。因为双主从模式下,主从同步关系很复杂,不能根据MySQL的状态来切换。只需要在一个主出问题后,切换到另外的主。

  • Ø heartbeat标签
    用于和后端数据库进行心跳检查的语句,检测MySQL数据库是否正常运行
    当switchType为1时,mysql心跳检查语句是select user()
    当switchType为2时,mysql心跳检查语句是show slave status
    当switchType为3时,mysql心跳检查语句是show status like ‘wsrep%’

  • Ø writeHost与readHost标签
    这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。唯一不同的是,writeHost指定写实例、readHost指定读实例,组合这些读写实例来满足系统的要求。

    在一个dataHost内可以定义多个writeHost和readHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去。

双主双从读写分离

以下以双主,双从为例子,按端口区分
3307主(3308、3309从)
3308主(3307、3310从)
3307、3308互为从

server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<!-- sequnceHandlerType
指定使用Mycat全局序列的类型:
0为本地文件方式,1为数据库方式,2为时间戳序列方式
对于读写分离而言,是不需要考虑主键生成方式的,也就是不需要配置全局序列号的。 -->
<property name="sequnceHandlerType">0</property>

<!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena-->
<property name="processorBufferPoolType">0</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">1m</property>

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

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

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


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

</system>

<!-- 配置之后可以使用mycat账号登录mysql,逻辑库mycatdb需要在schema.xml文件中配置映射的物理数据库 -->
<user name="mycat">
<property name="password">Peng@2020google</property>
<property name="schemas">mycatdb</property>
</user>

<user name="user">
<property name="password">Peng@2020google</property>
<property name="schemas">mycatdb</property>
<property name="readOnly">true</property>
</user>
</mycat:server>

schema

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

<!-- schema的name要与server.xml中的user<property name="schemas"></property>相同 -->
<schema name="mycatdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
<!-- 此处没有用到分表,不需要tablue标签 -->
</schema>

<!-- 此处的mycinema,在真实的数据库中必须存在 -->
<dataNode name="dn1" dataHost="localhost1" database="mycinema" />

<!-- 定义具体的数据库实例、读写分离配置和心跳语句; -->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">

<heartbeat>select user()</heartbeat>

<!-- 双主双从,用户名和密码都是真实的数据库 -->
<writeHost host="hostM3307" url="localhost:3307" user="root" password="Peng@2020google">
<!--配置写数据库下的读数据库(从库)-->
<readHost host="hostS3308" url="localhost:3308" user="root" password="Peng@2020google" />
<readHost host="hostS3309" url="localhost:3309" user="root" password="Peng@2020google" />
</writeHost>
<!-- 双主双从,用户名和密码都是真实的数据库 -->
<writeHost host="hostM3308" url="localhost:3308" user="root" password="Peng@2020google">
<!--配置写数据库下的读数据库(从库)-->
<readHost host="hostS3307" url="localhost:3307" user="root" password="Peng@2020google" />
<readHost host="hostS3310" url="localhost:3310" user="root" password="Peng@2020google" />
</writeHost>
</dataHost>
</mycat:schema>
```


### 测试
启动mycat服务
使用mysql登录mycat
`./mysql -umycat -p -P8066 -h 192.168.235.128`


## 一主三从读写分离
未测试过,测出省略server.xml表

Schema.xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycatdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
<!-- 只实现读写分离,没有涉及到分库分表,那么<schema>标签下不需要配置任何表 -->
</schema>
<!--配置真实的数据库名称 mycinema -->
<dataNode name="dn1" dataHost="localhost1" database="mycinema" />
<!--配置具体的数据库连接信息、读写分离、心跳语句 -->
<dataHost name="localhost1"
maxCon="1000"
minCon="10"
balance="1"
writeType="0"
dbType="mysql"
dbDriver="native"
switchType="1"
slaveThreshold="100">
<heartbeat>select user()</heartbeat>

<!--配置写数据库(主库) 一主三从的读写分离配置 -->
<writeHost host="hostM3307" url="localhost:3307" user="root" password="123456">
<!--配置写数据库下的读数据库(从库)-->
<readHost host="hostS3308" url="localhost:3308" user="root" password="123456" />
<readHost host="hostS3309" url="localhost:3309" user="root" password="123456" />
<readHost host="hostS3310" url="localhost:3310" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>

水平分表

一张表被拆到n个库中

一主三从

指定逻辑库,分片结点,结点主机等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycatdb" checkSQLschema="false" sqlMaxLimit="100">
<!-- 要实现分库分表,那么就需要在<schema>标签下配置表了,现在是水平切分 -->
<table name="orders" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="mod-long" />
</schema>
<!--配置真实的数据库名称 test01,test02,test03 -->
<dataNode name="dn1" dataHost="localhost1" database="test01" />
<dataNode name="dn2" dataHost="localhost1" database="test02" />
<dataNode name="dn3" dataHost="localhost1" database="test03" />

<!--配置具体的数据库连接信息、读写分离、心跳语句 -->
<dataHost name="localhost1"
maxCon="1000"
minCon="10"
balance="1"
writeType="0"
dbType="mysql"
dbDriver="native"
switchType="1"
slaveThreshold="100">

<!--配置心跳语句 -->
<heartbeat>select user()</heartbeat>
<!--配置写数据库一主三从的读写分离配置 -->
<writeHost host="hostM3307" url="localhost:3307" user="root" password="123456">
<!--配置写数据库下的读数据库(从库)-->
<readHost host="hostS3308" url="localhost:3308" user="root" password="123456" />
<readHost host="hostS3309" url="localhost:3309" user="root" password="123456" />
<readHost host="hostS3310" url="localhost:3310" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>

双主双从

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycatdb" checkSQLschema="false" sqlMaxLimit="100">
<!-- 要实现分库分表,那么就需要在<schema>标签下配置表了,现在是水平切分 -->
<table name="orders" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="mod-long" />
</schema>
<!--配置真实的数据库名称 test01,test02,test03 -->
<dataNode name="dn1" dataHost="localhost1" database="test01" />
<dataNode name="dn2" dataHost="localhost1" database="test02" />
<dataNode name="dn3" dataHost="localhost1" database="test03" />
<!--配置具体的数据库连接信息、读写分离、心跳语句 -->
<dataHost name="localhost1"
maxCon="1000"
minCon="10"
balance="1"
writeType="0"
dbType="mysql"
dbDriver="native"
switchType="1"
slaveThreshold="100">
<!--配置心跳语句 -->
<heartbeat>select user()</heartbeat>
<!--配置写数据库(主库) 双主双从的读写分离配置 -->
<writeHost host="hostM3307" url="localhost:3307" user="root" password="123456">
<!--配置写数据库下的读数据库(从库)-->
<readHost host="hostS3308" url="localhost:3308" user="root" password="123456" />
<readHost host="hostS3309" url="localhost:3309" user="root" password="123456" />
</writeHost>

<writeHost host="hostM3308" url="localhost:3308" user="root" password="123456">
<!--配置写数据库下的读数据库(从库)-->
<readHost host="hostS3307" url="localhost:3307" user="root" password="123456" />
<readHost host="hostS3310" url="localhost:3310" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>

配置rule.xml

在原有的rule的xml文件中,设置节点配置的数量

1
2
3
4
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- 节点分片数量 -->
<property name="count">3</property>
</function>

垂直分库

逻辑数据库与实际数据库的差别
双主双从

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycatdb" checkSQLschema="false" sqlMaxLimit="100">
<!-- 要实现分库分表,那么就需要在<schema>标签下配置表了,现在是垂直切分 -->
<!--需求:整个money平台的数据库(moneydb)进行垂直切分,分为前台数据库(money-web)、后台数据库(money-admin)-->
<!--money-web前台数据库-->
<table name="orders" primaryKey="id" autoIncrement="true" dataNode="dn1"/>
<table name="users" primaryKey="id" autoIncrement="true" dataNode="dn1"/>

<!--money-admin后台数据库-->
<table name="products" primaryKey="id" autoIncrement="true" dataNode="dn2"/>
<table name="news" primaryKey="id" autoIncrement="true" dataNode="dn2"/>
</schema>

<!--配置真实的数据库名称 testdb01 -->
<dataNode name="dn1" dataHost="localhost1" database="money-web" />
<dataNode name="dn2" dataHost="localhost1" database="money-admin" />

<!--配置具体的数据库连接信息、读写分离、心跳语句 -->
<dataHost name="localhost1"
maxCon="1000"
minCon="10"
balance="1"
writeType="0"
dbType="mysql"
dbDriver="native"
switchType="1"
slaveThreshold="100">
<!--配置心跳语句 -->
<heartbeat>select user()</heartbeat>

<!--配置写数据库(主库) 双主双从的读写分离配置 -->
<writeHost host="hostM3307" url="localhost:3307" user="root" password="123456">
<!--配置写数据库下的读数据库(从库)-->
<readHost host="hostS3308" url="localhost:3308" user="root" password="123456" />
<readHost host="hostS3309" url="localhost:3309" user="root" password="123456" />
</writeHost>
<writeHost host="hostM3308" url="localhost:3308" user="root" password="123456">
<!--配置写数据库下的读数据库(从库)-->
<readHost host="hostS3307" url="localhost:3307" user="root" password="123456" />
<readHost host="hostS3310" url="localhost:3310" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>

一主三从

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycatdb" checkSQLschema="false" sqlMaxLimit="100">
<table name="orders" primaryKey="id" autoIncrement="true" dataNode="dn1"/>
<table name="users" primaryKey="id" autoIncrement="true" dataNode="dn1"/>

<table name="products" primaryKey="id" autoIncrement="true" dataNode="dn2"/>
<table name="news" primaryKey="id" autoIncrement="true" dataNode="dn2"/>
</schema>

<dataNode name="dn1" dataHost="localhost1" database="money_web" />
<dataNode name="dn2" dataHost="localhost1" database="money_admin" />

<dataHost name="localhost1"
maxCon="1000"
minCon="10"
balance="1"
writeType="0"
dbType="mysql"
dbDriver="native"
switchType="1"
slaveThreshold="100">

<heartbeat>select user()</heartbeat>

<writeHost host="hostM3307" url="localhost:3307" user="root" password="123456">

<readHost host="hostS3308" url="localhost:3308" user="root" password="123456" />
<readHost host="hostS3309" url="localhost:3309" user="root" password="123456" />
<readHost host="hostS3310" url="localhost:3309" user="root" password="123456" />
</writeHost>

</dataHost>
</mycat:schema>

MyCat的主键生成方式

不管是何种方式的切分,主键生成必须交给MyCat实现,生成方式有四种

本地文件方式

  1. 修改conf/server.xml文件中配置sequnceHandlerType=0

  2. 在conf/sequence_conf.properties中维护主键信息

  3. 如果想要每个表生成的主键连续,可以在sequence_conf.properties配置当前表的生成值,一般将Global替换为自己对应的前缀即可(三个地方),取值的时候通过next value for MYCATSEQ_XXXX获取

    1
    2
    3
    INFO.CURID=1256
    INFO.MINID=3000
    INFO.MAXID=3000000
  1. 优点:本地加载,读取速度较快,配置简单

    缺点:mycat重新发布时,seq文件需要替换,集群部署无法用此方式,路由到不同的mycat上无法保证id唯一,使mycat变成了有状态的中间件

5.关闭服务,并重启

1
2
/usr/local/mycat/bin/mycat stop
/usr/local/mycat/bin/mycat start

6.测试

(1)创建测试表Info

1
2
3
CREATE TABLE info
(id VARCHAR(64) NOT NULL PRIMARY KEY,
NAME VARCHAR(50) NOT NULL);

(2)插入数据

1
INSERT INTO info (id,NAME) VALUES(NEXT VALUE FOR MYCATSEQ_INFO, '本地文件方式1');

本地时间戳方式

1.修改conf/server.xml文件中配置sequnceHandlerType=2

2.本地时间戳计算方式:

ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加) 长度18位,因此表主键字段长度必须大于等于18位

3.优点:不存在mycat重新发布影响seq的问题,

缺点:字段长度是18位,比较占空间

4.关闭服务,并重启

1
2
/usr/local/mycat/bin/mycat stop
/usr/local/mycat/bin/mycat start

5.测试

1
INSERT INTO info(NAME) VALUES('本地时间戳方式1');

结果如下图:

image-20211228145043961

数据库方式

1.修改conf/server.xml文件中配置sequnceHandlerType=1

2.在3307的money_admin数据库中执行以下代码,用于创建表MyCAT_SEQUENCE,生成序列值

MYCAT_SEQUENCE 的三个字段:

  • name sequence名称
  • current_value 当前value
  • increment 增长步长
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
DROP TABLE IF EXISTS MYCAT_SEQUENCE;
#创建表
CREATE TABLE MYCAT_SEQUENCE (
NAME VARCHAR(50) NOT NULL,
current_value INT NOT NULL,
increment INT NOT NULL DEFAULT 1,PRIMARY KEY(NAME))
ENGINE=INNODB DEFAULT CHARSET=utf8;
#插入数据
INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ("GLOBAL", 0, 10000);

#创建函数,处理当前值
DROP FUNCTION IF EXISTS mycat_seq_currval;
DELIMITER //
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 ;
#创建函数,设置序列值
DROP FUNCTION IF EXISTS mycat_seq_setval;
DELIMITER //
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 ;
#创建函数,处理序列的下一个值
DROP FUNCTION IF EXISTS mycat_seq_nextval;
DELIMITER //
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 ;

3.查看表mycat_sequence

1
SELECT * FROM mycat_sequence

image-20211228153708485

4.根据我们在schema.xml文件中的配置,money_admin数据库对应的节点应该是dn2,所以在sequence_db_conf.properties中配置的GLOBAL应该就是dn2

1
2
3
#sequence stored in datanode
GLOBAL=dn2
INFO=dn2

5.关闭mycat服务,并重启

1
2
/usr/local/mycat/bin/mycat stop
/usr/local/mycat/bin/mycat start

6.测试

1
2
3
INSERT INTO info(id,NAME) VALUES(NEXT VALUE FOR MYCATSEQ_GLOBAL,"数据库生成1");
INSERT INTO info(id,NAME) VALUES(NEXT VALUE FOR MYCATSEQ_GLOBAL,"数据库生成2");
INSERT INTO info(id,NAME) VALUES(NEXT VALUE FOR MYCATSEQ_GLOBAL,"数据库生成3");

结果如下图

image-20211228153215247

ZK方式

使用zookeeper服务器提供序列值,优点:无悲观锁,无强竞争,吞吐量更高。缺点:对zookeeper集群的要求增加