分布式id居然还能这么搞

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL DuckDB 分析主实例,集群系列 8核16GB
简介: 分布式id居然还能这么搞

微服务架构下为保证服务间数据强一致性,不得不依赖分布式唯一id来串联整个流程

生成ID的方法有很多,适应不同的场景、需求以及性能要求。我们常常为这个问题而纠结最终方案。下面就介绍一些常见的ID生成策略!!

常见算法

1. uuid

420995ed-d684-4c7b-a59f-c0ca708907a1
2e156d90-dc81-48cb-9313-9e6a9adb5218
9ce1fd17-603d-4984-bc69-c795852b0546

优点

性能非常高,本地生成,没有网络消耗

缺点

  • 不易存储,16字节128位,通常以36位长度的字符串表示,
  • 信息不安全,给予mac地址生成UUID 的算法可能会造成mac地址泄漏,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置
  • 用作mysql索引时,无序性会导致索引位置频繁变动,严重影响性能

2. snowflake

以划分命名空间来生成id 的一种算法,这种方案把64-bit分别分成多端,用来标识 机器、时间等

41-bit的时间可以表示(1L<<41)/(1000L360024*365)=69年的时间,10-bit机器可以分别表示1024台机器,12个字增序列 可以表示2^12个id,理论上 qps 可达 109.6w/s ,这种分配方式可以保证任一台机器在任何毫秒内生成的id 都是不同的。

优点:

  • 毫秒数在高位,自增序列在低位,整个id 都是趋势递增的
  • 不依赖任何第三方系统,以服务的方式部署,稳定性高,性能也不错。
  • 可以根据自身特性 分配 bit 位,比较灵活。

缺点:

  • 强烈依赖机器时钟,如果机器时钟回拨,会导致发号重复。

3. 数据库生成

利用自增id生成

优点:

非常简单,利用现有数据库系统的功能实现,成本小,有DBA专业维护。单调自增

缺点:

  • 强依赖DB,当DB异常时整个系统不可用,属于致命问题。配置主从复制可以尽可能的提高可用性,但主从切换时的不一致可能会导致重复信号。
  • id 发号性能瓶颈限制在单台mysql的读写性能。对于mysql性能问题,可以部署多台机器,每台机器设置不同的初始值,以及步长。假设有两台机器,设置步长为2 ,server1的初始值为1.(1,3,5,7,9)。server2的初始值为2.(2,4,6,8,10)。这样貌似能满足性能要求,但是将来在做扩容将恐怖如斯。

leaf 方案

本文的终极方案

Leaf是美团推出的一个分布式ID生成服务,这个名字是来自德国哲学家、数学家莱布尼茨的一句话:>There are no two identical leaves in the world > “世界上没有两片相同的树叶”。

Leaf在设计之初就秉承着几点要求:

  • 全局唯一,绝对不会出现重复的ID,且ID整体趋势递增。
  • 高可用,服务完全基于分布式架构,即使MySQL宕机,也能容忍一段时间的数据库不可用。
  • 高并发低延时,在CentOS 4C8G的虚拟机上,远程调用QPS可达5W+,TP99在1ms内。
  • 接入简单,直接通过公司RPC服务或者HTTP调用即可接入。

Leaf-segment号段模式

CREATE TABLE `leaf_id` 
( `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID', 
`max_id` bigint NOT NULL DEFAULT '0' COMMENT '当前最大的ID',`step` int NOT NULL DEFAULT '1000' COMMENT '步长', 
`biz_tag` varchar(100) NOT NULL COMMENT '业务信息', 
`description` varchar(100) DEFAULT NULL COMMENT '描述',
`version` bigint NOT NULL DEFAULT '0' COMMENT '版本号',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间', 
PRIMARY KEY (`id`), 
UNIQUE KEY `biz_tag` (`biz_tag`),
KEY `leaf_id_biz_tag_IDX` (`biz_tag`))
ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='leaf分布式id生成器';

基于号段模式采用了预分发的方式生成ID,在服务内存中维护一个固定长度的 id-list,

id由内存分发,所以可以做到很高效。至于数据持久化问题,leaf_server每次去DB拿固定长度的id-list,然后把最大的ID持久化下来(max_id),并非每个id都做持久化,仅仅持久化一批id中最大的那一个。server中 id号段分配至阈值时,通过这一段脚本

begin 
UPDATE table SET max_id=max_id+step WHERE biz_tag=xxxSELECT tag, max_id, step FROM table WHERE biz_tag=xxx 
commit

去申请新的号段区间维护在内存中

大家读到这里可能会想

咦?我这是分布式微服务架构啊,leaf_server 不是存在单点问题吗?如果leaf_server 挂了,整个服务都不可用了呀!!!但其实 leaf_server 也可水平扩展部署多台在不同的机房, 每一个server维护不同的号段 以支持服务的高可用

  • Leaf Server 1:从DB加载号段[1,1000]。
  • Leaf Server 2:从DB加载号段[1001,2000]。
  • Leaf Server 3:从DB加载号段[2001,3000]。

mysql 也可以做主从集群,由于号段维护在server 内存中,可撑过mysql 主从切换时的db不可用

总结

本文主要介绍了分布式id 的生成方案演进过程。

最后引出美团的leaf方案,基于Segment缓存模式的设计非常巧妙,保证了服务的性能以及高可用。

基于mysql的行锁,保证多leaf服务并发修改同一条数据场景下不会分配到同一号段,设计非常巧妙。但也有一定的缺点,就是 某台 leaf_server 宕机时,可能会造成号段不连续,某段id丢失,但整体还是趋势递增。

本文介绍并非全面,只是基于leaf_id 的核心思想展开叙述!!!

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
缓存 算法 NoSQL
【分布式详解】一致性算法、全局唯一ID、分布式锁、分布式事务、 分布式缓存、分布式任务、分布式会话
分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。副本一致性是针对分布式系统而言的,不是针对某一个副本而言。强一致性(strong consistency):任何时刻任何用户或节点都可以读到最近一次成功更新的副本数据。强一致性是程度最高的一致性要求,也是实践中最难以实现的一致性。单调一致性(monotonic consistency):任何时刻,任何用户一旦读到某个数据在某次更新后的值,这个用户不会再读到比这个值更旧的值。
1391 0
[go 面试] 雪花算法与分布式ID生成
[go 面试] 雪花算法与分布式ID生成
|
9月前
|
开发框架
osharp集成Yitter.IdGenerator并实现分布式ID
本文介绍了在 osharp 框架中集成 Yitter.IdGenerator 实现分布式 ID 的方法。osharp 是一个基于 .NET Core 的快速开发框架,而 Yitter.IdGenerator 是一种高效的分布式 ID 生成器。通过实现 `IKeyGenerator&lt;long&gt;` 接口并创建 `YitterSnowKeyGenerator` 类,结合 `YitterIdGeneratorPack` 模块化配置,实现了分布式环境下唯一 ID 的生成。
190 0
|
算法 关系型数据库 MySQL
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
在分布式系统中,确保每个节点生成的 ID 唯一且高效至关重要。Snowflake 算法由 Twitter 开发,通过 64 位 long 型数字生成全局唯一 ID,包括 1 位标识位、41 位时间戳、10 位机器 ID 和 12 位序列号。该算法具备全局唯一性、递增性、高可用性和高性能,适用于高并发场景,如电商促销时的大量订单生成。本文介绍了使用 Go 语言的 `bwmarrin/snowflake` 和 `sony/sonyflake` 库实现 Snowflake 算法的方法。
657 1
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
|
NoSQL 算法 关系型数据库
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
本文详解分布式全局唯一ID及其5种实现方案,关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
448 8
|
存储 SQL 算法
搞定了 6 种分布式ID,分库分表哪个适合做主键?
在《ShardingSphere5.x分库分表原理与实战》系列的第七篇文章中,作者探讨了分布式ID在分库分表中的重要性,以及如何利用`ShardingSphere-jdbc`的多种主键生成策略。文章介绍了`UUID`、`NanoID`、自定义雪花算法和`CosId`等策略的优缺点,并警告不要在SQL中手动拼接主键字段。此外,文章还展示了如何配置这些策略,并提醒读者`CosId`在5.2.0版本可能不可用。最后,文章讨论了如何自定义分布式主键生成算法,并强调选择策略时要考虑全局唯一性、性能和易用性。
1431 122
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
3822 2
深度思考:雪花算法snowflake分布式id生成原理详解
|
存储 NoSQL Java
通用快照方案问题之通过Sleuth进行耗时分析和链路优化如何解决
通用快照方案问题之通过Sleuth进行耗时分析和链路优化如何解决
157 0
|
消息中间件 Java Nacos
通用快照方案问题之通过Spring Cloud实现配置的自动更新如何解决
通用快照方案问题之通过Spring Cloud实现配置的自动更新如何解决
201 0

热门文章

最新文章