分布式id居然还能这么搞

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 分布式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 的核心思想展开叙述!!!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
缓存 算法 NoSQL
【分布式详解】一致性算法、全局唯一ID、分布式锁、分布式事务、 分布式缓存、分布式任务、分布式会话
分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。副本一致性是针对分布式系统而言的,不是针对某一个副本而言。强一致性(strong consistency):任何时刻任何用户或节点都可以读到最近一次成功更新的副本数据。强一致性是程度最高的一致性要求,也是实践中最难以实现的一致性。单调一致性(monotonic consistency):任何时刻,任何用户一旦读到某个数据在某次更新后的值,这个用户不会再读到比这个值更旧的值。
497 0
|
2天前
|
存储 算法 Java
分布式自增ID算法---雪花算法(SnowFlake)Java实现
分布式自增ID算法---雪花算法(SnowFlake)Java实现
|
1月前
|
存储 算法 Java
分布式唯一ID解决方案-雪花算法
分布式唯一ID解决方案-雪花算法
17 0
|
2月前
|
SQL 算法
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
50 1
|
2月前
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
429 2
深度思考:雪花算法snowflake分布式id生成原理详解
|
2月前
|
存储 SQL 算法
搞定了 6 种分布式ID,分库分表哪个适合做主键?
在《ShardingSphere5.x分库分表原理与实战》系列的第七篇文章中,作者探讨了分布式ID在分库分表中的重要性,以及如何利用`ShardingSphere-jdbc`的多种主键生成策略。文章介绍了`UUID`、`NanoID`、自定义雪花算法和`CosId`等策略的优缺点,并警告不要在SQL中手动拼接主键字段。此外,文章还展示了如何配置这些策略,并提醒读者`CosId`在5.2.0版本可能不可用。最后,文章讨论了如何自定义分布式主键生成算法,并强调选择策略时要考虑全局唯一性、性能和易用性。
328 1
|
2月前
|
算法 关系型数据库 MySQL
Go语言中的分布式ID生成器设计与实现
【5月更文挑战第6天】本文探讨了Go语言在分布式系统中生成全局唯一ID的策略,包括Twitter的Snowflake算法、UUID和MySQL自增ID。Snowflake算法通过时间戳、节点ID和序列号生成ID,Go实现中需处理时间回拨问题。UUID保证全局唯一,但长度较长。MySQL自增ID依赖数据库,可能造成性能瓶颈。选择策略时需考虑业务需求和并发、时间同步等挑战,以确保系统稳定可靠。
140 0
|
2月前
|
算法 Java 数据中心
分布式ID生成系统之雪花算法详解
在当今的云计算和微服务架构盛行的时代,分布式系统已成为软件开发的重要组成部分。随着系统规模的扩大和业务的复杂化,对数据一致性和唯一性的要求也越来越高,尤其是在全局唯一标识符(ID)的生成上。因此,分布式ID生成系统应运而生,成为保证数据唯一性和提高系统可扩展性的关键技术之一。雪花算法(Snowflake)是Twitter开源的一种算法,用于生成64位的全局唯一ID,非常适用于分布式系统中生成唯一标识符。下面我们将深入探讨雪花算法的原理、结构和实现方式。
173 2
 分布式ID生成系统之雪花算法详解
|
2月前
|
算法 NoSQL Java
Java实战:分布式ID生成方案
在分布式系统的设计与开发过程中,如何生成全局唯一、有序且高可用的ID是一个绕不开的核心问题。尤其是在电商、社交网络、金融交易等领域,ID不仅是业务数据的重要标识,还可能直接影响系统的稳定性和扩展性。本文将深入剖析分布式ID生成方案的设计原则、常见算法,并通过Java示例展示一种可行的实现方式。
105 2
|
2月前
|
NoSQL 算法 MongoDB
一文搞定分布式系统ID生成方案
一文搞定分布式系统ID生成方案
17 0