目录

一、全局序列号介绍

1、本地文件方式

2、数据库方式

3、本地时间戳方式

4、分布式 ZK ID 生成器

5、ZK 递增方式

6、其它方式

二、准备工作

环境

1、在 MySQL 建库

2、在 MySQL 建表

3、配置schema.xml 文件(按月分表)

4、配置 rule.xml 文件

5、配置 server.xml 文件

6、重新启动 mycat

7、查看表分片情况

三、配置方式详解

1、本地文件方式

1.1 修改配置文件 server.xml,指定加密方式为本地文件方式

1.2 在 schema.xml 文件中配置,增加表 t_im_msg_wf,msg_id 为主键,在 mycat_wf$1-3 分片上,分片方式为sharding-by-month

1.3 修改 sequence_conf.properties 文件中做如下配置:

1.4 重新启动 mycat

1.5 插入数据测试

1.6 测试成功总结

2、数据库方式

3、本地时间戳方式

3.1 修改配置文件 server.xml 配置

3.3 在 schema.xml 文件中配置,增加表 t_im_msg_wf,msg_id 为主键,在 mycat_wf$1-3 分片上,分片方式为sharding-by-month

3.4 重启 mycat

3.5 插入测试数据

3.6 测试成功总结

4、分布式 ZK ID 生成器

4.1 配置 zookeeper

4.2 配置 mycat

4.3 上面三个文件修改完成后,复制conf下的所有文件到 conf/zkconf/目录下,并授权

4.4 初始化

4.5 启动 mycat

4.6 测试mycat ZK 分布式ID生成器

4.7 测试成功总结

5、ZK 递增方式(配置同 4)

5.1 配置 sequence_distributed_conf.properties 通过配置文件配置InstanceID

5.2 配置 sequence_distributed_conf.properties 中 INSTANCEID=ZK 就是从ZK 上获取InstanceID

5.3 测试成功总结


一、全局序列号介绍

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

1、本地文件方式

使用服务器本地磁盘文件的方式

2、数据库方式

使用专用数据库方式

3、本地时间戳方式

使用时间戳算法方式

4、分布式 ZK ID 生成器

基于 ZK 与本地配置的分布式 ID 生成器(可以通过 ZK 获取集群(机房)唯一 InstanceID,也可以通过配置文件配置 InstanceID)

5、ZK 递增方式

另一种 ZK 生成方式

6、其它方式

二、准备工作

环境

MySQL:5.7.16

MyCAT:1.6.5

Zookeeper:3.4.9

JDK:1.8.0_144

1、在 MySQL 建库

mysql> create database if not exists mycat_wf1;
Query OK, 1 row affected (0.01 sec)mysql> create database if not exists mycat_wf2;
Query OK, 1 row affected (0.00 sec)mysql> create database if not exists mycat_wf3;
Query OK, 1 row affected (0.00 sec)

2、在 MySQL 建表

CREATE TABLE if not exists `t_im_msg_wf` (`msg_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,`fromid` bigint(20) unsigned NOT NULL,`toid` bigint(20) unsigned NOT NULL DEFAULT '0',`chatfrom` bigint(20) unsigned NOT NULL,`chatto` bigint(20) unsigned NOT NULL DEFAULT '0',`group_id` int(10) DEFAULT '0' COMMENT '群组id',`shop_id` bigint(20) unsigned NOT NULL DEFAULT '0',`pub_id` int(10) DEFAULT '0' COMMENT '消息类型:0表示普通类型,1表示平台客服',`channel_id` tinyint(4) DEFAULT '2' COMMENT '区分平台:1表示美丽说,2表示higo',`msg` text COMMENT '消息内容',`ctime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`msg_sharding_date` date NOT NULL COMMENT '消息分区日期',`ext` text COMMENT '扩展信息json_encode',`source`  varchar(10) NOT NULL DEFAULT 'web' COMMENT '信息来源',`type` varchar(16) DEFAULT '' COMMENT '消息类型',`is_read` tinyint(4) DEFAULT '0' COMMENT '消息状态:1表示已读,0表示未读',`source_ip` bigint(20) unsigned NOT NULL DEFAULT '0',`is_del` tinyint(4) DEFAULT '0' COMMENT '消息状态:1表示删除,0表示正常',PRIMARY KEY (`msg_id`),KEY `mix_fromto` (`chatfrom`,`chatto`,`is_read`),KEY `mix_fromto2` (`fromid`,`toid`,`is_read`),KEY `idx_group_id` (`group_id`),KEY `idx_ctime` (`ctime`),KEY `idx_msg_date` (`msg_sharding_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户聊天记录存储表';

3、配置schema.xml 文件(按月分表)

<schema name="msg_wf" checkSQLschema="false" ><table name="t_im_msg_wf" primaryKey="msg_id" dataNode="mycat_wf$1-3" rule="sharding-by-month" />
</schema><dataNode name="mycat_wf$1-3" dataHost="localhost1" database="mycat_wf$1-3" />

4、配置 rule.xml 文件

<tableRule name="sharding-by-month"><rule><columns>msg_sharding_date</columns><algorithm>partbymonth</algorithm></rule>
</tableRule><function name="partbymonth"class="io.mycat.route.function.PartitionByMonth"><property name="dateFormat">yyyy-MM-dd</property><property name="sBeginDate">2019-01-01</property>
</function>

5、配置 server.xml 文件

<user name="wufei"><property name="password">wufei</property><property name="schemas">msg_wf</property>
</user>

6、重新启动 mycat

# ./mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...

7、查看表分片情况

# mysql -uwufei -pwufei -h127.0.0.1 -P3025mysql> show databases;
+--------------------+
| DATABASE           |
+--------------------+
| msg_wf             |
+--------------------+
27 rows in set (0.01 sec)mysql> use msg_wf
Database changed
mysql> show tables;
+------------------+
| Tables in msg_wf |
+------------------+
| t_im_msg_wf      |
+------------------+
1 row in set (0.00 sec)mysql> explain select * from t_im_msg_wf;
+-----------+---------------------------+
| DATA_NODE | SQL                       |
+-----------+---------------------------+
| mycat_wf1 | select * from t_im_msg_wf |
| mycat_wf2 | select * from t_im_msg_wf |
| mycat_wf3 | select * from t_im_msg_wf |
+-----------+---------------------------+
3 rows in set (0.04 sec)mysql> show create table t_im_msg_wf \G;
*************************** 1. row ***************************Table: t_im_msg_wf
Create Table: CREATE TABLE `t_im_msg_wf` (`msg_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,`fromid` bigint(20) unsigned NOT NULL,`toid` bigint(20) unsigned NOT NULL DEFAULT '0',`chatfrom` bigint(20) unsigned NOT NULL,`chatto` bigint(20) unsigned NOT NULL DEFAULT '0',`group_id` int(10) DEFAULT '0' COMMENT '群组id',`shop_id` bigint(20) unsigned NOT NULL DEFAULT '0',`pub_id` int(10) DEFAULT '0' COMMENT '消息类型:0表示普通类型,1表示平台客服',`channel_id` tinyint(4) DEFAULT '2' COMMENT '区分平台:1表示美丽说,2表示higo',`msg` text COMMENT '消息内容',`ctime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`msg_sharding_date` date NOT NULL COMMENT '消息分区日期',`ext` text COMMENT '扩展信息json_encode',`source` varchar(10) NOT NULL DEFAULT 'web' COMMENT '信息来源',`type` varchar(16) DEFAULT '' COMMENT '消息类型',`is_read` tinyint(4) DEFAULT '0' COMMENT '消息状态:1表示已读,0表示未读',`source_ip` bigint(20) unsigned NOT NULL DEFAULT '0',`is_del` tinyint(4) DEFAULT '0' COMMENT '消息状态:1表示删除,0表示正常',PRIMARY KEY (`msg_id`),KEY `mix_fromto` (`chatfrom`,`chatto`,`is_read`),KEY `mix_fromto2` (`fromid`,`toid`,`is_read`),KEY `idx_group_id` (`group_id`),KEY `idx_ctime` (`ctime`),KEY `idx_msg_date` (`msg_sharding_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户聊天记录存储表'
1 row in set (0.01 sec)mysql> explain select * from t_im_msg_wf where msg_sharding_date='2019-01-01';
+-----------+----------------------------------------------------------------+
| DATA_NODE | SQL                                                            |
+-----------+----------------------------------------------------------------+
| mycat_wf1 | select * from t_im_msg_wf where msg_sharding_date='2019-01-01' |
+-----------+----------------------------------------------------------------+
1 row in set (0.02 sec)mysql> explain select * from t_im_msg_wf where msg_sharding_date='2019-02-01';
+-----------+----------------------------------------------------------------+
| DATA_NODE | SQL                                                            |
+-----------+----------------------------------------------------------------+
| mycat_wf2 | select * from t_im_msg_wf where msg_sharding_date='2019-02-01' |
+-----------+----------------------------------------------------------------+
1 row in set (0.00 sec)mysql> explain select * from t_im_msg_wf where msg_sharding_date between'2019-03-01' and '2019-03-31';
+-----------+----------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                   |
+-----------+----------------------------------------------------------------------------------------+
| mycat_wf1 | select * from t_im_msg_wf where msg_sharding_date between'2019-03-01' and '2019-03-31' |
+-----------+----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

三、配置方式详解

1、本地文件方式

配置方式:

在sequence_conf.properties文件中做如下配置:

# default global sequence(这是全局表的设置)
GLOBAL.HISIDS=
GLOBAL.MINID=10001
GLOBAL.MAXID=20000
GLOBAL.CURID=10000# self define sequence(下面是自定义表的设置)

其中HISIDS 表示使用过的历史分段(一般无特殊需要可不配置),MINID 表示最小ID 值,MAXID 表示最大

ID 值,CURID 表示当前ID 值。

server.xml 中配置

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

注:sequnceHandlerType 需要配置为0,表示使用本地文件方式;1 表示专用数据库方式。

使用示例:

insert into t_im_msg_wf(msg_id,fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(next value for MYCATSEQ_GLOBAL,283099513902353978,0,1201367170,0,5166,0,'','2019-01-09 11:03:35','2019-01-09','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);

缺点:当MyCAT 重新发布后,配置文件中的sequence 会恢复到初始值(重启 MyCAT 需要重新配置sequence_conf.properties文件)。

优点:本地加载,读取速度较快。

【本地文件方式详细配置及测试】

1.1 修改配置文件 server.xml,指定加密方式为本地文件方式

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

1.2 在 schema.xml 文件中配置,增加表 t_im_msg_wf,msg_id 为主键,在 mycat_wf$1-3 分片上,分片方式为sharding-by-month

<schema name="msg_wf" checkSQLschema="false" ><table name="t_im_msg_wf" primaryKey="msg_id" autoIncrement="true" dataNode="mycat_wf$1-3" rule="sharding-by-month" />
</schema>

1.3 修改 sequence_conf.properties 文件中做如下配置:

#default global sequence
GLOBAL.HISIDS=
GLOBAL.MINID=10001
GLOBAL.MAXID=20000
GLOBAL.CURID=10000# self define sequence
T_IM_MSG_WF.HISIDS=
T_IM_MSG_WF.MINID=1788000601
T_IM_MSG_WF.MAXID=2788000601
T_IM_MSG_WF.CURID=1788000600

1.4 重新启动 mycat

1.5 插入数据测试

插入一条使用T_IM_MSG_WF序列号的数据

insert into t_im_msg_wf(msg_id,fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(next value for MYCATSEQ_T_IM_MSG_WF,283099513902353978,0,1201367170,0,5166,0,'','2019-01-09 11:03:35','2019-01-09','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);

查看序列号使用

mysql> select * from t_im_msg_wf \G;
*************************** 1. row ***************************msg_id: 1788000601fromid: 283099513902353978toid: 0chatfrom: 1201367170chatto: 0group_id: 5166shop_id: 0pub_id: 0channel_id: 2msg:ctime: 2019-01-09 11:03:35
msg_sharding_date: 2019-01-09ext: {"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}source: pandoratype: higo_buyis_read: 0source_ip: 169082962is_del: 0
1 row in set (0.02 sec)

根据分区间多插入一些数据

mysql> select msg_id,ctime,msg_sharding_date from t_im_msg_wf;
+------------+---------------------+-------------------+
| msg_id     | ctime               | msg_sharding_date |
+------------+---------------------+-------------------+
| 1788000602 | 2019-02-07 11:03:35 | 2019-02-07        |
| 1788000601 | 2019-01-09 11:03:35 | 2019-01-09        |
| 1788000603 | 2019-03-07 11:03:35 | 2019-03-07        |
+------------+---------------------+-------------------+
3 rows in set (0.00 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-02-07';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf2 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-02-07' |
+-----------+---------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-01-09';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf1 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-01-09' |
+-----------+---------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-03-07';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf3 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-03-07' |
+-----------+-----------------------------------

这些数据在分片上的情况

mysql> select msg_id,ctime,msg_sharding_date from mycat_wf1.t_im_msg_wf;
+------------+---------------------+-------------------+
| msg_id     | ctime               | msg_sharding_date |
+------------+---------------------+-------------------+
| 1788000601 | 2019-01-09 11:03:35 | 2019-01-09        |
+------------+---------------------+-------------------+
1 row in set (0.00 sec)mysql> select msg_id,ctime,msg_sharding_date from mycat_wf2.t_im_msg_wf;
+------------+---------------------+-------------------+
| msg_id     | ctime               | msg_sharding_date |
+------------+---------------------+-------------------+
| 1788000602 | 2019-02-07 11:03:35 | 2019-02-07        |
+------------+---------------------+-------------------+
1 row in set (0.00 sec)mysql> select msg_id,ctime,msg_sharding_date from mycat_wf3.t_im_msg_wf;
+------------+---------------------+-------------------+
| msg_id     | ctime               | msg_sharding_date |
+------------+---------------------+-------------------+
| 1788000603 | 2019-03-07 11:03:35 | 2019-03-07        |
+------------+---------------------+-------------------+
1 row in set (0.00 sec)

1.6 测试成功总结

优点:配置简单,本地文件,读写速度快

缺点:导致MYCAT变成有状态的中间件,不利于部署集群

2、数据库方式

数据库方式存在比较明显的缺点,即MYCAT集群切换和保持序列的数据库主从切换之后,不可控内容较多 需要非常仔细的处理这些问题,维护成本较高,虽然实现MYCAT无状态,但有单点问题。

即在数据库中建立一张表,存放sequence名称(name),sequence当前值(current_value),步长(increment,int类型每次读取多少个sequence,假设为K)等信息

3、本地时间戳方式

ID= 64 位二进制 (1(标识)+41(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加) 

即换算成十进制为18位数的long类型,每毫秒可以并发12位二进制的累加。

具体实现算法:什么是 SnowFlake 算法❓

3.1 修改配置文件 server.xml 配置

<property name="sequnceHandlerType">2</property>
<!-- 注:sequnceHandlerType 需要配置为2,表示使用本地时间戳生成sequence -->

3.2 修改 sequence_time_conf.properties 文件配置

  • #sequence depend on TIME
  • DATAACENTERID=01 #0-31任意整数
  • WORKID=01 #0-31任意整数
  • 多个个mycat节点下每个mycat配置的 WORKID,DATAACENTERID不同,组成唯一标识,总共支持32*32=1024种组合

3.3 在 schema.xml 文件中配置,增加表 t_im_msg_wf,msg_id 为主键,在 mycat_wf$1-3 分片上,分片方式为sharding-by-month

<schema name="msg_wf" checkSQLschema="false" ><table name="t_im_msg_wf" primaryKey="msg_id" autoIncrement="true" dataNode="mycat_wf$1-3" rule="sharding-by-month" />
</schema>

3.4 重启 mycat

3.5 插入测试数据

插入一条使用本地时间戳方式的数据

mysql> insert into t_im_msg_wf(fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(283099513902353978,0,1201367170,0,5166,0,'','2019-01-09 11:03:35','2019-01-09','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);

Query OK, 1 row affected (0.03 sec)

暂不支持主键为null如:

mysql> insert into t_im_msg_wf(msg_id,fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(null,283099513902353978,0,1201367170,0,5166,0,'','2019-01-09 11:03:35','2019-01-09','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);

查看时间戳方式的使用

mysql> select * from t_im_msg_wf \G; *************************** 1. row ***************************msg_id: 1126345984591400960fromid: 283099513902353978toid: 0chatfrom: 1201367170chatto: 0group_id: 5166shop_id: 0pub_id: 0channel_id: 2msg:ctime: 2019-01-09 11:03:35
msg_sharding_date: 2019-01-09ext: {"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}source: pandoratype: higo_buyis_read: 0source_ip: 169082962is_del: 0
1 row in set (0.00 sec)

根据分区键多插入一些数据

mysql> select msg_id,ctime,msg_sharding_date from t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 1126345984591400960 | 2019-01-09 11:03:35 | 2019-01-09        |
| 1126347203393228800 | 2019-03-07 11:03:35 | 2019-03-07        |
| 1126347125572112384 | 2019-02-07 11:03:35 | 2019-02-07        |
+---------------------+---------------------+-------------------+
3 rows in set (0.00 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-01-09';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf1 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-01-09' |
+-----------+---------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-02-07';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf2 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-02-07' |
+-----------+---------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-03-07';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf3 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-03-07' |
+-----------+---------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

这些数据在分片上的情况

mysql> select msg_id,ctime,msg_sharding_date from mycat_wf1.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 1126345984591400960 | 2019-01-09 11:03:35 | 2019-01-09        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)mysql> select msg_id,ctime,msg_sharding_date from mycat_wf2.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 1126347125572112384 | 2019-02-07 11:03:35 | 2019-02-07        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)mysql> select msg_id,ctime,msg_sharding_date from mycat_wf3.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 1126347203393228800 | 2019-03-07 11:03:35 | 2019-03-07        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)

3.6 测试成功总结

是个好方式

优点:不会出现以上两种方式因mycat重启导致sequence重复。

缺点:需要重构 IM 中关联 msg_id 的业务

4、分布式 ZK ID 生成器

配置选项:

<property name="sequnceHandlerType">3</property>

原理说明:

Zk 的连接信息统一在myid.properties 的zkURL 属性中配置。

基于ZK 与本地配置的分布式ID 生成器(可以通过ZK 获取集群(机房)唯一InstanceID,也可以通过配置文件配置InstanceID)ID 结构:long 64 位,ID 最大可占63 位

current time millis(微秒时间戳38 位,可以使用17 年)

instanceId(实例ID,可以通过ZK 或者配置文件获取,5 位,也就是十进制0-31)

threadId(线程ID,9 位)

increment(自增,6 位)

一共63 位,可以承受单机房单机器单线程1000*(2^6)=640000 的并发。

无悲观锁,无强竞争,吞吐量更高
配置文件:sequence_distributed_conf.properties,只要配置里面:INSTANCEID=ZK 就是从ZK 上获取InstanceID。

4.1 配置 zookeeper

zookeeper是hadoop的一个子项目

一般生产上需要配置zookeeper集群,奇数个节点,至少三个节点

为了测试mycat的相关特性,我们只搭建一个单节点的zookeeper

安装Zookeeper:

# tar -zxvf zookeeper-3.4.9.tar.gz -C /data/monitor/

# cd /data/monitor/zookeeper-3.4.9

将conf目录下的zoo_sample.cfg重命名为zoo.cfg

# cd conf

# cp zoo_sample.cfg zoo.cfg

# vim zoo.cfg

tickTime=2000

dataDir=/data/hadoop/storage/zookeeper

clientPort=2181

initLimit=5

syncLimit=2

启动zookeeper

# cd /data/monitor/zookeeper-3.4.9/bin

# ./zkServer.sh start | stop

注意:防火墙的配置自行处理

ZooKeeper 分布式模式(搭建生产网络或夸机房分布式的时候再进行补充)

4.2 配置 mycat

修改 myid.properties 文件(注意真正的配置文件中不要再配置参数后再加#的注释,并且检查参数后是否有空格)

loadZk=true    #使用zk管理mycat和ID
zkURL=127.0.0.1:2181    #zk服务器的地址和端口
clusterId=010    #本机房mycat集群的ID
myid=01001    #集群内mycat的ID
clusterSize=1
clusterNodes=mycat_inf    #mycat节点的名称
#server  booster  ;   booster install on db same server,will reset all minCon to 2
#type=server
#boosterDataHosts=dn1,dn2

修改 server.xml 文件

<property name="sequnceHandlerType">3</property>
<!-- 3:zookeeper分布式管理模式 -->
<property name="defaultSqlParser">druidparser</property><property name="useCompression">1</property>

修改 sequence_distributed_conf.properties 文件

只要配置里面:INSTANCEID=ZK 就是从ZK 上获取InstanceID,否则通过配置文件配置InstanceID。

NSTANCEID=ZK #代表使用zk

CLUSTERID=010 #与myid.properties中的CLUSTERID设置的值相同

# INSTANCEID=01
NSTANCEID=ZK
CLUSTERID=010

4.3 上面三个文件修改完成后,复制conf下的所有文件到 conf/zkconf/目录下,并授权

# cp *.txt *.xml *.properties zkconf/

# chown -R zkconf/

4.4 初始化

# cd /data/mycat-1.6.5/mycat/bin

# ./init_zk_data.sh

4.5 启动 mycat

先使用console看看启动是否正常

# ./mycat console
Running Mycat-server...
wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
jvm 1    | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1    |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
jvm 1    |
jvm 1    | MyCAT Server startup successfully. see logs in logs/mycat.log

正常之后再正常启动

# ./mycat status
Mycat-server is not running.
# ./mycat start
Starting Mycat-server...
# ./mycat status
Mycat-server is running (48470).

4.6 测试mycat ZK 分布式ID生成器

插入一条使用ZK 分布式ID生成器方式的数据

mysql> insert into t_im_msg_wf(fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(283099513902353978,0,1201367170,0,5166,0,'','2019-01-09 11:03:35','2019-01-09','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);

Query OK, 1 row affected (0.03 sec)

暂不支持主键为null如:

mysql> insert into t_im_msg_wf(msg_id,fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(null,283099513902353978,0,1201367170,0,5166,0,'','2019-01-09 11:03:35','2019-01-09','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);

查看ZK 分布式ID生成器方式的使用

mysql> select * from t_im_msg_wf \G;
*************************** 1. row ***************************msg_id: 6141013758699405312fromid: 283099513902353978toid: 0chatfrom: 1201367170chatto: 0group_id: 5166shop_id: 0pub_id: 0channel_id: 2msg:ctime: 2019-01-09 11:03:35
msg_sharding_date: 2019-01-09ext: {"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}source: pandoratype: higo_buyis_read: 0source_ip: 169082962is_del: 0
1 row in set (0.00 sec)

根据分区键多插入一些数据

mysql> select msg_id,ctime,msg_sharding_date from t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 6141013758699405312 | 2019-01-09 11:03:35 | 2019-01-09        |
| 6141021747808337984 | 2019-02-07 11:03:35 | 2019-02-07        |
| 6141022380074500224 | 2019-03-07 11:03:35 | 2019-03-07        |
+---------------------+---------------------+-------------------+
3 rows in set (0.00 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-01-09';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf1 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-01-09' |
+-----------+---------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-02-07';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf2 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-02-07' |
+-----------+---------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> explain select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-03-07';
+-----------+---------------------------------------------------------------------------------------------+
| DATA_NODE | SQL                                                                                         |
+-----------+---------------------------------------------------------------------------------------------+
| mycat_wf3 | select msg_id,ctime,msg_sharding_date from t_im_msg_wf where msg_sharding_date='2019-03-07' |
+-----------+---------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

这些数据在分片上的情况

mysql> select msg_id,ctime,msg_sharding_date from mycat_wf1.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 6141013758699405312 | 2019-01-09 11:03:35 | 2019-01-09        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)mysql> select msg_id,ctime,msg_sharding_date from mycat_wf2.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 6141021747808337984 | 2019-02-07 11:03:35 | 2019-02-07        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)mysql> select msg_id,ctime,msg_sharding_date from mycat_wf3.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 6141022380074500224 | 2019-03-07 11:03:35 | 2019-03-07        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)

4.7 测试成功总结

只是ID 非递增。

5、ZK 递增方式(配置同 4)

<property name="sequnceHandlerType">4</property>
<!-- 4:zookeeper自增分布式管理模式 -->
<property name="defaultSqlParser">druidparser</property>
<property name="useCompression">1</property>

5.1 配置 sequence_distributed_conf.properties 通过配置文件配置InstanceID

INSTANCEID=01
CLUSTERID=010

插入多条使用递增ZK 分布式ID生成器方式的数据,并查看

mysql> insert into t_im_msg_wf(fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(283099513902353978,0,1201367170,0,5166,0,'','2019-01-09 11:03:35','2019-01-09','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);
Query OK, 1 row affected (0.06 sec)mysql> insert into t_im_msg_wf(fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(283099513902353978,0,1201367170,0,5166,0,'','2019-02-07 11:03:35','2019-02-07','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);
Query OK, 1 row affected (0.04 sec)mysql> insert into t_im_msg_wf(fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(283099513902353978,0,1201367170,0,5166,0,'','2019-03-07 11:03:35','2019-03-07','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);
Query OK, 1 row affected (0.03 sec)mysql> select msg_id,msg_sharding_date from t_im_msg_wf order by msg_id asc;
+------------+-------------------+
| msg_id     | msg_sharding_date |
+------------+-------------------+
| 2788000603 | 2019-01-09        |
| 3788000604 | 2019-02-07        |
| 4788000605 | 2019-03-07        |
+------------+-------------------+
3 rows in set (0.02 sec)

5.2 配置 sequence_distributed_conf.properties 中 INSTANCEID=ZK 就是从ZK 上获取InstanceID

NSTANCEID=ZK
CLUSTERID=010

插入多条使用递增ZK 分布式ID生成器方式的数据,并查看

mysql> insert into t_im_msg_wf(fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(283099513902353978,0,1201367170,0,5166,0,'','2019-01-17 11:03:35','2019-01-17','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);
Query OK, 1 row affected (0.00 sec)mysql> insert into t_im_msg_wf(fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(283099513902353978,0,1201367170,0,5166,0,'','2019-02-17 11:03:35','2019-02-17','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);
Query OK, 1 row affected (0.01 sec)mysql> insert into t_im_msg_wf(fromid,toid,chatfrom,chatto,group_id,shop_id,msg,ctime,msg_sharding_date,ext,source,type,source_ip) values(283099513902353978,0,1201367170,0,5166,0,'','2019-03-17 11:03:35','2019-03-17','{"buy":"林阳刚买了 韩国 呼吸SUM37苏秘 呼吸惊喜水份套盒 6只安瓶 清爽补水 收毛孔 !","buy_goodsid":"176204663976998975"}','pandora','higo_buy',169082962);
Query OK, 1 row affected (0.01 sec)mysql> select msg_id,msg_sharding_date from t_im_msg_wf order by msg_id asc;
+---------------------+-------------------+
| msg_id              | msg_sharding_date |
+---------------------+-------------------+
| 6141088719535374400 | 2019-01-17        |
| 6141089312307970176 | 2019-02-17        |
| 6141089922595979456 | 2019-03-17        |
+---------------------+-------------------+
3 rows in set (0.00 sec)

这些数据在分片上的情况

mysql> select msg_id,ctime,msg_sharding_date from mycat_wf1.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 6141088719535374400 | 2019-01-17 11:03:35 | 2019-01-17        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)mysql> select msg_id,ctime,msg_sharding_date from mycat_wf2.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 6141089312307970176 | 2019-02-17 11:03:35 | 2019-02-17        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)mysql> select msg_id,ctime,msg_sharding_date from mycat_wf2.t_im_msg_wf;
+---------------------+---------------------+-------------------+
| msg_id              | ctime               | msg_sharding_date |
+---------------------+---------------------+-------------------+
| 6141089312307970176 | 2019-02-17 11:03:35 | 2019-02-17        |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)

5.3 测试成功总结

分布式ZK ID生成器还是很强大,这为数据库跨机房双活提供了新的方案,使得双A机房架构下的数据最终一致性有了新的思路。

Mycat 分片表全局自增主键实现及测试相关推荐

  1. Mybatis返回Mysql表的自增主键

    2019独角兽企业重金招聘Python工程师标准>>> <insert id="insertUplusDns" parameterType="co ...

  2. Mysql表用自增主键的选型

    文章目录 1. 版本说明 2. 说明 3. 场景选型 1. 版本说明 基于mysql版本:5.6.27 mysql数据库引擎:InnoDb 2. 说明 InnoDb的索引特性,导致的自增id做主键是效 ...

  3. oracle表增加自增主键,Oracle中给已存在的表增加自增主键

    大致方式是,创建新表,将旧表数据复制到新表,同时通过Oracle的触发器+Sequence实现主键自增: 1.创建字段相同多且只多一个字段的新表: 略 2.创建Sequence: CREATE SEQ ...

  4. SQL获取第一个表的自增主键并作为另一个表的外键

    方式一:@@IDENTITY table1为主表,主键为自增的ID,在插入数据时ID不需要被赋值,自动插入:table2为从表,jlid为外键,与table1中的ID关联. 现在传入一条数据,需要同时 ...

  5. mysql主键自增 insert_MySQL数据表中有自增长主键时如何插入数据

    https://jingyan.baidu.com/article/fcb5aff7b3a025edaa4a7130.html 设置自增列 phpmyadmin 把A_I选中 就是AUTO_INCRE ...

  6. 数据库面试 - 分库分表之后,id 主键如何处理?

    数据库面试 - 分库分表之后,id 主键如何处理? 面试题 分库分表之后,id 主键如何处理? 面试官心理分析 其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后, ...

  7. MySQL导入csv文件内容到Table及数据库的自增主键设置

    写在前面 目的是测试将csv文件内容导入到表中, 同时记录一下自增主键的设置. 测试采用MySQL8.0. 新建表customer_info如下, 未设置主键. 修改上表, 添加主键id, 并设置为自 ...

  8. mysql linux导入csv主键,MySQL导入csv文件内容到Table及数据库的自增主键设置

    写在前面 目的是测试将csv文件内容导入到表中, 同时记录一下自增主键的设置. 测试采用MySQL8.0. 新建表customer_info如下, 未设置主键. 修改上表, 添加主键id, 并设置为自 ...

  9. Mysql 自增主键设置以及重置自增值

    一.自增主键设置 CREATE TABLE `table_name` (`IncreaseId` INT(16) NOT NULL AUTO_INCREMENT COMMENT '自增主键',`Ins ...

最新文章

  1. c语言多组输入字符,关于c语言中 scanf 对多行字符的输入问题
  2. android wifi调试
  3. fatal error C1010:unexpected end of file while looking for precompiled header directive报错的解决办法
  4. linux 基于qt assistant制作软件帮助文档,基于Qt Assistant的软件帮助系统
  5. qt服务器获取formdata文件,QT上传(PUT)文件
  6. ETL异构数据源Datax_限速设置_06
  7. 智能车辆手册 pdf_SIMULINK在虚拟车辆开发方面的应用
  8. 成功破解:世界杀软“金奖”得主BitDefender 2008(官方中文版 + 注册机下载)
  9. 具有增删改查及英汉互译功能的英汉互译词典
  10. FixFox 打包xpi扩展
  11. 详细讲一下delphi里的 IF 语句
  12. 原生JS获取dom元素高度
  13. 等比矩阵求和-POJ3233
  14. win10+Ubuntu16.04+Quadro P600双系统安装以及独显驱动安装
  15. Python简单词云的制作
  16. 什么是真正的转运?常见的五种转运方法
  17. 【API接口】接口上线下线 用户在线测试,和管理员发布api待完善...
  18. 记录 ESIM 安装、使用过程中遇到的问题
  19. 脱离文档流和恢复文档流的方法
  20. 重师者王,重友者霸,重己者亡

热门文章

  1. STM32F407 DP83848驱动调试过程总结(标准库到HAL库移植避坑指南)
  2. 3389之永不查杀的后门shift后门代码
  3. 启用Win8/10(中文版/核心版/家庭版)中被阉割的远程桌面服务端
  4. ROS API查看——Zeal
  5. Ping和Traceroute原理
  6. matlab 马尔可夫链代码
  7. 大四学生想在成都找一个实习的工作机会
  8. mysql插入错误:1110-Column ‘id‘ specified twice和1064-you can‘t set value for Autoincrement column
  9. AI达人特训营]印度vs津巴布韦!板球比赛语义分割
  10. 海德堡印刷机显示屏维修SDU10_00.785.1384显示器维修故障概述