加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Mysql系列七:分库分表技术难题之分布式全局唯一id解决方案

发布时间:2020-12-11 23:57:44 所属栏目:MySql教程 来源:网络整理
导读:一、前言 在前面的文章中,已经说过分库分表需要应对的技术难题有如下几个: 1. 分布式全局唯一id 2. 分片规则和策略 3. 跨分片技术问题 4. 跨分片事物问题 下面我们来看一下Mycat是如何解决分布式全局唯一id的问题的 二、Mycat全局序列号 Mycat保证id唯一的

一、前言

在前面的文章中,已经说过分库分表需要应对的技术难题有如下几个:

1. 分布式全局唯一id

2. 分片规则和策略

3. 跨分片技术问题

4. 跨分片事物问题

下面我们来看一下Mycat是如何解决分布式全局唯一id的问题的

二、Mycat全局序列号

Mycat保证id唯一的方式有如下几个:

1)本地文件方式

2)数据库方式

3)时间戳方式

4)ZKID生成器

5)ZK递增ID

4,5

以上5中方式都要统一在server.xml文件中开启全局序列号的配置和在schema.xml文件中配置逻辑表的autoIncrement属性为true(2个必须步骤)

1)sequnceHandlerType进行相应全局序列号策略选项设置(server.xml),在mycat中对应的源码是MyCATSequnceProcessor.java

0

  sequnceHandlerType可取的值有以下几个:

    0:本地文件方式    1:数据库方式    2:时间戳方式    3:ZKID生成器    4:ZK递增ID

2)autoIncrement属性为true(schema.xml)

1. 本地文件方式

使用到的mycat源码:io.mycat.route.sequence.handler.IncrSequenceHandler

?在server.xml文件中开启全局序列号的配置:

0

使用到的配置文件:sequence_conf.properties

self define sequence

COMPANY.HISIDS=
COMPANY.MINID=1001
COMPANY.MAXID=2000
COMPANY.CURID=1000

CUSTOMER.HISIDS=
CUSTOMER.MINID=1001
CUSTOMER.MAXID=2000
CUSTOMER.CURID=1000

ORDER.HISIDS=
ORDER.MINID=1001
ORDER.MAXID=2000
ORDER.CURID=1000

HOTNEWS.HISIDS=
HOTNEWS.MINID=1001
HOTNEWS.MAXID=2000
HOTNEWS.CURID=1000

拿HOTNEWS这个表的配置来说明:

示例:

1.1 在mycat的schema.xml文件里面分别配置逻辑表hotnews和mysql的主从机,注意autoIncrement="true"才能使用全局唯一id

select user()

1.2 在主数据库(192.168.152.130)分别创建3个数据库db1,db2,db3,然后创建hotnews表

() () );
<span style="color: #0000ff">create
<span style="color: #0000ff">database
<span style="color: #000000"> db2;
<span style="color: #0000ff">use
<span style="color: #000000"> db2;
<span style="color: #0000ff">create
<span style="color: #0000ff">table
<span style="color: #000000"> hotnews(
id
<span style="color: #0000ff">bigint
(<span style="color: #800000; font-weight: bold">20
) <span style="color: #808080">not
<span style="color: #0000ff">null
<span style="color: #0000ff">primary
<span style="color: #0000ff">key
<span style="color: #000000"> auto_increment,title
<span style="color: #0000ff">varchar
(<span style="color: #800000; font-weight: bold">50
) <span style="color: #0000ff">default
<span style="color: #0000ff">null
<span style="color: #000000">

);
<span style="color: #0000ff">create <span style="color: #0000ff">database<span style="color: #000000"> db3;
<span style="color: #0000ff">use<span style="color: #000000"> db3;
<span style="color: #0000ff">create <span style="color: #0000ff">table<span style="color: #000000"> hotnews(
id <span style="color: #0000ff">bigint(<span style="color: #800000; font-weight: bold">20) <span style="color: #808080">not <span style="color: #0000ff">null <span style="color: #0000ff">primary <span style="color: #0000ff">key<span style="color: #000000"> auto_increment,title <span style="color: #0000ff">varchar(<span style="color: #800000; font-weight: bold">50) <span style="color: #0000ff">default <span style="color: #0000ff">null<span style="color: #000000">

);

1.3 插入数据

插入数据到hotnews前我们先来看一下使用本地文件方式的配置文件sequence_conf.properties的内容

cat sequence_conf.properties grep HOTNEWS

插入数据到hotnews

hotnews(id,title) ( value MYCATSEQ_HOTNEWS, hotnews(id, hotnews(id,);

1.4 查看hotnews表的结果

hotnews;

再次查看配置文件sequence_conf.properties的内容,发现内容随着插入数据的自增id做了改变

2. 数据库方式

这种方式和本地文件的方式是一样的,只是把sequence_conf.properties的内容用数据库来管理

使用到的mycat源码:io.mycat.route.sequence.handler.IncrSequenceMySQLHandler

这里还是以hotnews表为例

2.1 在server.xml文件中开启全局序列号的配置:

1

使用到的配置文件:sequence_db_conf.properties

vim sequence_db_conf.properties
#sequence stored dn1

2.2 选择其中的一个分片,执行如下步骤,譬如我在dn1中创建,对应的数据库名为db1(为什么这里会涉及到datanode,因为后续的sequence_db_conf.properties文件会使用到),注意:是登录到数据库中创建,而不是在mycat中创建

第一步:创建SEQUENCE表,用来存储序列号

() , , , INNODB ;?INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('GLOBAL',100000,100);

第二步:创建SEQ function

`mycat_seq_currval`(seq_name ( ( retval ( retval", concat((current_value ),",(increment ) ) MYCAT_SEQUENCE name <span style="color: #008080">--<span style="color: #008080"> 获取下一个sequence值
<span style="color: #0000ff">DROP
<span style="color: #0000ff">FUNCTION
<span style="color: #0000ff">IF
<span style="color: #808080">EXISTS
<span style="color: #000000"> mycat_seq_nextval;
DELIMITER ;;
<span style="color: #0000ff">CREATE
<span style="color: #0000ff">FUNCTION
mycat_seq_nextval(seq_name <span style="color: #0000ff">VARCHAR
(<span style="color: #800000; font-weight: bold">50
)) <span style="color: #0000ff">RETURNS
<span style="color: #0000ff">varchar
(<span style="color: #800000; font-weight: bold">64
<span style="color: #000000">)
CHARSET utf8
DETERMINISTIC
<span style="color: #0000ff">BEGIN
<span style="color: #0000ff">UPDATE
<span style="color: #000000"> MYCAT_SEQUENCE
<span style="color: #0000ff">SET
current_value <span style="color: #808080">=
current_value <span style="color: #808080">+
<span style="color: #000000"> increment
<span style="color: #0000ff">WHERE
name <span style="color: #808080">=
<span style="color: #000000"> seq_name;
<span style="color: #0000ff">RETURN
<span style="color: #000000"> mycat_seq_currval(seq_name);
<span style="color: #0000ff">END
<span style="color: #000000">
;;
DELIMITER ;

<span style="color: #008080">--<span style="color: #008080"> 设置sequence值
<span style="color: #0000ff">DROP <span style="color: #0000ff">FUNCTION <span style="color: #0000ff">IF <span style="color: #808080">EXISTS<span style="color: #000000"> mycat_seq_setval;
DELIMITER ;;
<span style="color: #0000ff">CREATE <span style="color: #0000ff">FUNCTION mycat_seq_setval(seq_name <span style="color: #0000ff">VARCHAR(<span style="color: #800000; font-weight: bold">50),value <span style="color: #0000ff">INTEGER<span style="color: #000000">)
<span style="color: #0000ff">RETURNS <span style="color: #0000ff">varchar(<span style="color: #800000; font-weight: bold">64<span style="color: #000000">) CHARSET utf8
DETERMINISTIC
<span style="color: #0000ff">BEGIN <span style="color: #0000ff">UPDATE<span style="color: #000000"> MYCAT_SEQUENCE
<span style="color: #0000ff">SET current_value <span style="color: #808080">=<span style="color: #000000"> value
<span style="color: #0000ff">WHERE name <span style="color: #808080">=<span style="color: #000000"> seq_name;
<span style="color: #0000ff">RETURN<span style="color: #000000"> mycat_seq_currval(seq_name);
<span style="color: #0000ff">END<span style="color: #000000">
;;
DELIMITER ;

插入需要自增长的表的策略,这条数据是我们hotnews这个表所需要的。 name必须是大写的字符,不然就会报错?

MYCAT_SEQUENCE (,,);

说明:插入了一个名为HOTNEWS的sequence,当前值为101,步长为100。当插入第一条数据时id为201,后面每插入一条数据id加1

第三步:在sequence_db_conf.properties这个文件中定义hotnews这张表的序列名称,同时可以定义到哪个分片上。这里是定义在dn1上的

      名字=分片1[,分片2][,.....][,分片N]

vim sequence_db_conf.properties

保存:

:wq

2.3 重启mycat

# .binmycat restart;

2.4 连接mycat进行数据测试

mysql uroot p123456 P8066 h192..

插入数据

hotnews(id, hotnews(id, hotnews(id,);

查看结果:

hotnews;

缺点:当mycat挂掉时可能出现主键冲突。不推荐使用

3.?本地时间戳方式

使用到的mycat源码:io.mycat.route.sequence.handler.IncrSequenceTimeHandler

3.1 在server.xml文件中开启全局序列号的配置:

2

使用到的配置文件:

sequence_time_conf.properties

          WORKID=01(范围01-31)

          DATAACENTERID=01(范围01-31)

示例:

首先清空hotnews这张表的数据,方便查看测试结果

hotnews;

插入测试数据

hotnews(id,title) ( value MYCATSEQ_GLOBAL, hotnews(id, hotnews(id,);

查看结果:

hotnews;

优点:不存在id重复的现象。

缺点:主键太长。时间可能被重置。没有特殊要求的场景可以使用

4.?自增长主键

方式1:不同自增长初始值+相同步长

方式2:参考“数据库方式”

5.?分布式ZK ID生成

环境准备:先在虚拟机192.168.152.130里面装好zookeeper,具体参考我的文章?

5.1 在server.xml文件中开启全局序列号的配置:

vim server.xml

3

5.2 修改如下配置文件:

1)myid.properties

vim myid.properties

配置文件说明:

loadZK=true|false //

zkURL=xxx.xxx.xxx.xxx:2182,xxx.xxx.xxx.xxx:2182,xxx.xxx.xxx.xxx:2182

clusterId=

2)sequence_distributed_conf.properties

vim sequence_distributed_conf.properties

配置文件说明:

INSTANCEID=ZK ?//

CLUSTERID=01 ??//集群

5.3 重启mycat

# .binmycat restart;

5.4 连接mycat进行数据测试

mysql -uroot -p123456 -P8066 -h192.168.152.128

插入数据

hotnews(id, hotnews(id, hotnews(id,

查看结果:

hotnews;

6. ZK递增方式

使用到的mycat源码:io.mycat.route.sequence.handler.IncrSequenceZKHandler

6.1 在server.xml文件中开启全局序列号的配置:

vim server.xml

4

使用到的配置文件:

1) myid.properties 参考“5. 分布式ZK ID生成器”中的介绍。

2)?sequence_conf.properties

说明:

hotnewsMAXID和MINID1000MAXID和MINID的偏移量

6.2 重启mycat

[root@centos1 mycat]# ./bin/mycat restart;

6.3? 连接mycat进行数据测试

mysql -uroot -p123456 -P8066 -h192.168.152.128

插入数据

hotnews(id,);

查看结果:

hotnews;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读