我的编程空间,编程开发者的网络收藏夹
学习永远不晚

mycat分片表全局自增主键测试

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

mycat分片表全局自增主键测试

mycat分片表全局自增主键测试

mycat分片表全局自增主键测试

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

1.本地文件方式

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

2.数据库方式
使用专用数据库的方式

3.本地时间戳方式
使用时间戳算法方式

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

5.Zk 递增方式
另一种ZK生成方式

6.其他方式

二、配置方式详解
1.本地文件方式

配置方式:
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>

注:sequnceHandlerType 需要配置为0,表示使用本地文件方式。
使用示例:
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);

缺点:当MyCAT 重新发布后,配置文件中的sequence 会恢复到初始值。
优点:本地加载,读取速度较快。

[本地文件方式详细配置和测试]

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

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

1.2 在schema.xml文件中配置,增加表tt,ID为主键,在dn$1-3上分片,分片方式mod-log
<table name="tt" primaryKey="id" autoIncrement="true" dataNode="dn$1-3" rule="mod-long"/>

1.3 修改sequence_conf.properties 文件中做如下配置:
# 这是全局表的设置
GLOBAL.HISIDS=
GLOBAL.MINID=10001
GLOBAL.MAXID=1000000000
GLOBAL.CURID=10000

# 下面是自定义表的设置
TT.HISIDS=
TT.MINID=1001
TT.MAXID=2000
TT.CURID=1000

1.4 建表tt
CREATE TABLE tt(
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name_` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

查看表结构
mysql> desc tt;                                      
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name_ | int(10) unsigned | NO   |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

查看表分片情况
mysql> explain select * from tt;
+-----------+--------------------------------+
| DATA_NODE | SQL                            |
+-----------+--------------------------------+
| dn1       | SELECT * FROM tt LIMIT 3000000 |
| dn2       | SELECT * FROM tt LIMIT 3000000 |
| dn3       | SELECT * FROM tt LIMIT 3000000 |
+-----------+--------------------------------+
3 rows in set (0.07 sec)

1.5 插入数据测试
插入一条使用全局序列号
insert into tt(id,name_) values(next value for MYCATSEQ_GLOBAL,1);

查看序列号使用
mysql> SELECT * FROM TT;
+-------+-------+
| id    | name_ |
+-------+-------+
| 10001 |     1 |
+-------+-------+
1 row in set (0.00 sec)

插入一条使用TT序列号
insert into tt(id,name_) values(next value for MYCATSEQ_TT,2);

查看序列好使用情况
mysql> SELECT * FROM TT ORDER BY name_;
+-------+-------+
| id    | name_ |
+-------+-------+
| 10001 |     1 |
|  1001 |     2 |
+-------+-------+
2 rows in set (0.01 sec)

多插入一些数据,查询结果
mysql> SELECT * FROM TT ORDER BY name_;                              
+-------+-------+
| id    | name_ |
+-------+-------+
| 10001 |     1 |
|  1001 |     2 |
|  1002 |     3 |
|  1003 |     4 |
|  1004 |     5 |
|  1005 |     6 |
+-------+-------+
6 rows in set (0.00 sec)

这些数据再分片上的情况
mysql (db1)>select * from tt;
+------+-------+
| id   | name_ |
+------+-------+
| 1002 |     3 |
| 1005 |     6 |
+------+-------+
2 rows in set (0.00 sec)

mysql (db2)>select * from tt;
+------+-------+
| id   | name_ |
+------+-------+
| 1003 |     4 |
+------+-------+
1 row in set (0.00 sec)

mysql (db3)>select * from tt;
+-------+-------+
| id    | name_ |
+-------+-------+
|  1001 |     2 |
|  1004 |     5 |
| 10001 |     1 |
+-------+-------+

OK It works!!

优点:配置简单,本地文件,读写速度快
缺点:导致MYCAT变成有状态的中间件,不利于部署集群

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

ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
server.xml

<system><property name="sequnceHandlerType">2</property></system>

sequence_time_conf.properties
WORKID=0-31 任意整数
DATAACENTERID=0-31 任意整数

是个好方式

4.分布式ZK ID 生成器

-----最想测试的还是这个

配置选项:

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

原理说明:
Zk 的连接信息统一在myid.propertieszkURL 属性中配置。
基于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

配置ZK ID生成器的主要步骤

4.1 配置zookeeper

zookeeper是hadoop的一个子项目
一般生产上需要配置zookeeper集群,奇数个节点,至少三个节点
为了测试mycat的相关特性,我们只搭建一个单节点的zookeeper

ZooKeeper Standalone模式

从Apache网站上(zookeeper.apache.org)下载ZooKeeper软件包,我选择了3.3.4版本的(zookeeper-3.3.4.tar.gz),在一台Linux机器上安装非常容易,只需要解压缩后,简单配置一下即可以启动ZooKeeper服务器进程。

将zookeeper-3.3.4/conf目录下面的 zoo_sample.cfg修改为zoo.cfg,配置文件内容如下所示:

tickTime=2000
dataDir=/home/hadoop/storage/zookeeper
clientPort=2181
initLimit=5
syncLimit=2

下面启动ZooKeeper服务器进程:
cd zookeeper-3.3.4/
bin/zkServer.sh start

这样zookeeper就可以使用了,防火墙的配置自行处理

ZooKeeper 分布式模式
搭建生产网络或夸机房分布式的时候再进行补充
4.2 配置mycat

主要涉及三个方面,修改myid.properties,修改server.xml,修改sequence_distributed_conf.properties

myid.properties:

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

server.xml:
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
        <property name="defaultSqlParser">druidparser</property>
        <property name="useCompression">1</property>
        <property name="serverPort">3306</property>
        <property name="managerPort">3308</property>
        <property name="maxStringLiteralLength">65535</property>
        <!-- sequnceHandlerType 0:文件模式 1: 2:3:zookeeper分布式管理模式 -->
        <property name="sequnceHandlerType">3</property>
    </system>
    <user name="root">
        <property name="password">password</property>
        <property name="schemas">dbykt</property>
    </user>
</mycat:server>

sequence_distributed_conf.properties:
INSTANCEID=01
CLUSTERID=01

上面三个文件修改完成后,复制conf下的所有文件到 conf/zkconf/目录下
cp *.txt *.xml *.properties zkconf/

初始化:
cd ./bin/
./init_zk_data.sh

4.3 启动mycat

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

./bin/mycat console

正常之后再进行启动
./bin/mycat start

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

使用工具Jmeter,此处不赘述

配置表ot1:

.....
<table name="ot1" dataNode="dn$1-20,dn$21-40,dn$41-60" rule="card_no" primaryKey="id" autoIncrement="true"/>
......

重启mycat
./bin/mycat restart

建表(因为同时测试了插入性能,所以表较为复杂)
CREATE TABLE `ot1` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
...............
...............

  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Jmeter 插入数据测试
使用的sql语句如下:
INSERT INTO `ot1` (
    `id`,
................
................
 

)
VALUES
    (
        next value for MYCATSEQ_OT,
...............
...............
 
    );

查询观察结果
mysql> SELECT id FROM ot1 ORDER BY id;

........

| 3894484648986705980 |
| 3894484648986705981 |
| 3894484649020260414 |
| 3894484649053814784 |
| 3894484649053814847 |
| 3894484649389359105 |
| 3894484649926230018 |
| 3894484649926230019 |
| 3894484649926230020 |
| 3894484649926230021 |
| 3894484649959784454 |
| 3894484649959784455 |
| 3894484649959784456 |
| 3894484649993338889 |
| 3894484649993338890 |
| 3894484650026893323 |
| 3894484650026893324 |
| 3894484650060447757 |
| 3894484650060447758 |
| 3894484650094002191 |
........

查询数据总量:
mysql> select count(id) id_count from ot1;
+----------+
| id_count |
+----------+
| 37784391 |
+----------+

查出最大ID:
mysql> select max(id) id from ot1 ;
+---------------------+
| id                  |
+---------------------+
| 3897338173617897525 |
+---------------------+
1 row in set (0.03 sec)

判断一下是否有重复ID:
mysql> select count(id),id from ot1 group by id having count(id)>1;

Empty set (1 min 42.85 sec)

4.5 结论

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

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

mycat分片表全局自增主键测试

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MyCat教程六:全局序列号-全局主键的自增长

前面我们介绍了MyCat的分库分表操作,那么同一张表中的数据会被保存在不同的数据库中,那么这就涉及到了主键维护的问题,此时肯定不能使用单个数据库中id自增的方式来处理了,这时我们就可以通过MyCat中提供的几种增长的方式来实现 全局主键自增 一、本地文件自增方
MyCat教程六:全局序列号-全局主键的自增长
2016-04-17

编程热搜

目录