十种分布式ID生成方法

什么是分布式ID

以MySQL为例,数据量不大的时候,单库单表可以支撑现有业务,再大一点主从同步读写分离也可以。
但数据是不断增加的,当主从同步也不行了,就需要分库分表了。分库分表需要一个全局唯一ID做标识,这就是分布式ID。一个能生成分布式ID的系统是十分有必要的。

分布式ID特点

  • 全局唯一:基本要求
  • 高性能:高可用低延时,ID生成相应快,否则成为业务瓶颈;
  • 高可用:不能有单点故障
  • 好接入:在系统设计和实现上尽可能地简单;
  • 趋势递增:在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用B-tree的数据结构来存储索引数据,我们应该尽量使用有序的主键保证写入性能;
  • 单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序。
  • 信息安全:在一些应用场景下,会需要ID无规则、不规则生成,例如订单号。
  • 分片支持:可以控制ShardingId。比如某一个用户的文章要放在同一个分片内,这样查询效率高,修改也容易。
  • 长度适中

生成方式

  1. UUID
  2. 数据库自增ID
  3. 数据库多主模式
  4. 数据库号段模式
  5. Redis
  6. 雪花算法(SnowFlake)
  7. 滴滴出品(TinyID)
  8. 百度(Uidgenerator)
  9. 美团(Leaf)
  10. zookeeper

1.UUID

UUID uuid=UUID.randomUUID();

UUID的标准形式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:550e8400-e29b-41d4-a716-446655440000。这种ID每个都是独一无二的,不用担心冲突问题。
优点:

  • 生成简单,本地生成无网络消耗,有唯一性

缺点:

  • 无序字符串,不具备趋势递增的特性;
  • 没有具体含义;
  • 长度过长对MySQL性能消耗较大;
  • 基于MAC地址生成的UUID可能造成MAC地址泄露

2.数据库自增ID

基于数据库的auto_increment自增ID完全可以充当分布式ID,需要一个单独的MySQL实例用来生成ID,建表结构如下:

CREATE DATABASE `SEQ_ID`;
CREATE TABLE SEQID.SEQUENCE_ID (
    id bigint(20) unsigned NOT NULL auto_increment, 
    value char(10) NOT NULL default '',
    PRIMARY KEY (id),
) ENGINE=MyISAM;
insert into SEQUENCE_ID(value)  VALUES ('values');

当我们需要一个ID的时候,向表中插入一条记录返回主键ID

优点:

  • 简单,利用数据库系统功能实现,成本小,有DBA专业维护
  • ID号单调递增

缺点:

  • 太依赖DB,当DB异常时整个系统不可用,属于致命问题。
  • 配置主从复制可以尽可能的增加可用性,但是数据一致性在特殊情况下难以保证。主从切换时的不一致可能会导致重复发号。
  • ID发号性能瓶颈限制在单台MySQL的读写性能
  • 访问量激增时MySQL本身就是系统的瓶颈,用它来实现分布式服务风险比较大

3.数据库多主模式

对上边的方式做一些高可用优化,换成主从模式集群。再增加多几个Mysql实例,那就是多主模式集群了。

设置起始值和自增步长来解决重复ID的问题,例如:
MySQL_1起始值为1,步长为2,生成ID:1,3,5…
MySQL_2起始值为2,步长为2,生成ID:2,4,6…
当添加多一个MySQL_3时,起始值为3,步长统一改为3,那么就是
1,4,7…
2,5,8…
3,6,9…

优点:解决DB单点问题
缺点:不利于后续扩容,而且实际上单个数据库自身压力还是大,依旧无法满足高并发场景

4.数据库号段模式

从数据库批量的获取自增ID,每次从数据库取出一个号段范围,例如 (1,1000] 代表1000个ID,具体的业务服务将本号段,生成1~1000的自增ID并加载到内存。表结构如下:

CREATE TABLE id_generator (
  id int(10) NOT NULL,
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值