当前位置: 首页 > 工具软件 > iD > 使用案例 >

【分布式篇】什么是分布式ID?分布式ID常见解决方案有哪些?

曾弘扬
2023-12-01

分布式ID

什么是分布式ID

在分库之后, 数据遍布在不同服务器上的数据库,数据库的自增主键已经没办法满足生成的主键唯一了

个人理解:分布式系统下,在分库分表之后唯一识别ID

分布式ID需要满足的需求

基本需求:

  • 全局唯一 :ID 的全局唯一性肯定是首先要满足的!
  • 高性能 : 分布式 ID 的生成速度要快,对本地资源消耗要小。(生成速度快
  • 高可用 :生成分布式 ID 的服务要保证可用性无限接近于 100%。(服务禁止挂掉!!
  • 方便易用 :拿来即用,使用方便,快速接入!(代码方便写

其他需求

  • 安全 :ID 中不包含敏感信息(如用户)。
  • 有序递增 :如果要把 ID 存放在数据库的话,ID 的有序性可以提升数据库写入速度。并且,很多时候 ,我们还很有可能会直接通过 ID 来进行排序。
  • 有具体的业务含义 :生成的 ID 如果能有具体的业务含义,可以让定位问题以及开发更透明化(通过 ID 就能确定是哪个业务)。
  • 独立部署 :也就是分布式系统单独有一个发号器服务,专门用来生成分布式 ID。这样就生成 ID 的服务可以和业务相关的服务解耦。不过,这样同样带来了网络调用消耗增加的问题。总的来说,如果需要用到分布式 ID 的场景比较多的话,独立部署的发号器服务还是很有必要的。(保证高可用

分布式 ID 常见解决方案

原文地址:JavaGuide 分布式 ID 常见解决方案

从以下三个维度去分析

1. 数据库维度

基于数据库主键自增实现

CREATE TABLE `sequence_id` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `stub` char(10) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  UNIQUE KEY `stub` (`stub`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
优点 :

实现起来比较简单、ID 有序递增、存储消耗空间小

缺点 :

支持的并发量不大、存在数据库单点问题(使用主从模式来提高可用性)

基于数据库的号段模式实现(重要,Leaf和Tinyid框架基于这个模式)

批量获取然后存在在内存里面,需要用到的时候,直接从内存里面拿就可以了

号:ID号,段:一段一段的取

CREATE TABLE `sequence_id_generator` (
  `id` int(10) NOT NULL,
  `current_max_id` bigint(20) NOT NULL COMMENT '当前最大id',
  `step` int(10) NOT NULL COMMENT '号段的长度',
  `version` int(20) NOT NULL COMMENT '版本号',
  `biz_type`    int(20) NOT NULL COMMENT '业务类型',
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  • current_max_id 字段和step字段主要用于获取批量 ID,获取的批量 id 为: current_max_id ~ current_max_id+step。
  • version 字段主要用于解决并发问题(乐观锁),biz_type 主要用于表示业务类型。

相比于数据库主键自增的方式,数据库的号段模式对于数据库的访问次数更少,数据库压力更小。另外,为了避免单点问题,你可以从使用主从模式来提高可用性。

优点 :
  • ID 有序递增、存储消耗空间小
  • 对于数据库的访问次数更少,数据库压力更小
缺点 :

存在数据库单点问题(使用主从模式来提高可用性)

基于Redis集群实现

使用incr命令保证原子性地递增ID

127.0.0.1:6379> set sequence_id_biz_type 1
OK
127.0.0.1:6379> incr sequence_id_biz_type
(integer) 2
127.0.0.1:6379> get sequence_id_biz_type
"2"
优点 :

性能不错并且生成的 ID 是有序递增的

缺点 :

存在单点问题,所以要做成Redis集群

2. 算法维度

UUID

比如使用 UUID 作为 MySQL 数据库主键的时候就非常不合适:

  • 数据库主键要尽量越短越好,而 UUID 的消耗的存储空间比较大(32 个字符串,128 位)。
  • UUID 是无顺序的,InnoDB 引擎下,数据库主键的无序性会严重影响数据库性能
优点 :

生成速度比较快、简单易用

缺点 :
  • 存储消耗空间大(32 个字符串,128 位)
  • 不安全(基于 MAC 地址生成 UUID 的算法会造成 MAC 地址泄露)、无序(非自增)、没有具体业务含义
  • 需要解决重复 ID 问题(当机器时间不对的情况下,可能导致会产生重复 ID)

雪花算法

优点 :
  • 生成速度比较快、生成的 ID 有序递增、比较灵活(可以对 Snowflake 算法进行简单的改造比如加入业务 ID)
  • 有很多基于 Snowflake 算法的开源实现比如美团 的 Leaf百度的 UidGenerator,并且这些开源实现对原有的 Snowflake 算法进行了优化。
缺点 :

需要解决重复 ID 问题(依赖时间,当机器时间不对的情况下,可能导致会产生重复 ID)。

3. 开源框架维度

UidGenerator(百度)

UidGenerator 是百度开源的一款**基于 Snowflake(雪花算法)**的唯一 ID 生成器。

Leaf(美团,世界上没有两片相同的树叶)

Leaf 提供了 号段模式Snowflake(雪花算法) 这两种模式来生成分布式 ID。

Tinyid(滴滴)

Tinyid 是滴滴开源的一款基于数据库号段模式的唯一 ID 生成器。

 类似资料: