分布式 ID(Distributed ID)是指在分布式系统中生成全局唯一的标识符,用于标识不同实体或数据对象。在分布式系统中,由于数据存储、计算和处理都分散在不同的节点上,因此需要一个可靠的方式来跟踪和标识这些数据对象。
分布式ID最低要求:
erlang
复制代码
优秀的分布式 ID
复制代码
数据库自增ID是在数据库中创建表时,通过设置一个自增的ID字段来实现的。每当插入一条记录时,数据库会自动为该记录生成一个唯一的ID。
数据库自增ID可以很好地保证ID的唯一性,但在高并发和大规模的分布式系统中,容易出现瓶颈和性能问题。同时,由于数据库自增ID只能在单个数据库中保证唯一性,因此需要通过分库分表等方式来支持多台机器上的生成。
简言之:
复制代码
数据库主键自增这种模式,每次获取 ID 都要访问一次数据库,数据库压力大。因此,可以批量获取,然后存在内存里面,需要用到的时候,直接从内存里面拿来使用
主键自增
erlang
复制代码
号段模式:每请求一次分配一个号段
复制代码
号段模式相比主键自增而言: 性能提高且自增
Redis 可以通过自增命令来实现分布式 ID 的生成。常用的方法是使用 Redis 的自增命令 INCR,将一个特定的 key 自增,并将其作为 ID 返回。这种方法是线程安全的,可以在分布式系统中使用
复制代码
MongoDB ObjectId是MongoDB数据库中的一个内置数据类型,用于唯一标识MongoDB文档(Document)。
它由12个字节组成,其中前4个字节表示时间戳,接下来3个字节表示机器ID,然后2个字节表示进程ID,最后3个字节表示随机值。
优缺点:
复制代码
UUID是一种通用唯一识别码,它是由一组算法和标准组成的,可以保证在全球范围内唯一性。UUID不依赖于任何中心节点,可以在分布式系统中很好地保证ID的唯一性。缺点是它生成的ID比较长,不利于索引和查询
开放软件基金会(OSF)规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素。利用这些元素来生成UUID。
优缺点:
css
复制代码
雪花算法是 Twitter 提出的一种分布式ID生成算法。雪花算法可以在多台机器上生成不重复的ID,支持高并发和大规模的分布式系统,但需要保证数据中心ID和机器ID的唯一性。
它的原理是将一个64位的long类型的ID分为4个部分:时间戳、数据中心ID、机器ID和序列号。
时间戳占用了42位,可以使用69年,数据中心ID和机器ID分别占用了5位,可以支持32个数据中心和32个机器,序列号占用了12位,可以支持每个节点每毫秒生成4096个ID。
细一点说:生成的64位ID可以分成5个部分:
复制代码
时间范围
markdown
复制代码
工作进程数量
ini
复制代码
序列号数量
ini
复制代码
默认情况下41bit的时间戳可以支持该算法使用到2082年,10bit的工作机器id可以支持1024台机器,序列号支持1毫秒产生4096个自增序列id 。SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右
优缺点:
复制代码
java
复制代码
application.ym添加配置
java
复制代码
IdWorker添加到容器
java
复制代码
UidGenerator是百度开源的一款基于 Snowflake的唯一 ID 生成器,是对 Snowflake进行了改进
GitHub:
Tinyid是滴滴开源的一款基于数据库号段模式的唯一 ID 生成器。
GitHub:
Leaf是美团开源的一个分布式 ID 解决方案。提供了号段模式 和 Snowflake这两种模式来生成分布式 ID。
目前Leaf覆盖了美团点评公司内部金融、餐饮、外卖、酒店旅游、猫眼电影等众多业务线。在4C8G VM基础上,通过公司RPC方式调用,QPS压测结果近5w/s,TP999 1ms。
Leaf 设计文档:
GitHub:
makefile
复制代码
bash
复制代码
sql
复制代码
xml
复制代码
Leaf 提供两种生成的ID的方式(号段模式和snowflake模式),可以同时开启两种方式,也可以指定开启某种方式(默认两种方式为关闭状态)。
ini
复制代码
bash
复制代码
在classpath下配置leaf.properties
bash
复制代码
算法取自twitter开源的snowflake算法。如果不想使用该模式配置leaf.snowflake.enable=false即可。
在classpath下配置leaf.properties
matlab
复制代码
bash
复制代码
css
复制代码
java
复制代码
java
复制代码
参数key无实际意义,受迫于统一接口的实现
java
复制代码
号段模式中该参数key有着重要意义
数据库表初始时
访问地址:
请求获取id值后,号段模式提前加载
重启服务后再次访问,使用新的号段
号段模式再一次提前加载