ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

分布式系统唯一 ID 生成器全解:5 种主流方案原理、优缺点与选型指南(System Design 101)

分布式系统唯一 ID 生成器全解:5 种主流方案原理、优缺点与选型指南(System Design 101) 后端文档教程【免费下载链接】system-design-101Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.项目地址https://gitcode.com/GitHub_Trending/sy/system-design-101点击查看免费下载在分布式系统与高并发业务中如何为海量数据生成全局唯一、排序友好、且性能足够的 ID是后端架构中最常见也最容易被忽略的基础问题。本指南以仓库中的《Explaining 5 Unique ID Generators》文档为核心系统讲解 UUID、Snowflake、数据库自增、数据库号段与 Redis 五种主流 ID 生成方案的实现原理、适用场景与取舍权衡并结合 data/guides/unique-id-generator.md 中的需求定义与仓库其他相关资料帮助你建立完整的方案选型框架为系统设计面试与生产架构决策提供可直接引用的知识基础。为什么需要专门设计分布式 ID 生成器在单体系统中数据库自增主键通常已经够用但一旦系统走向微服务化、分库分表或多机房部署单一数据库的自增主键就无法满足跨节点的唯一性需求。此时我们需要一套独立于具体业务表、能够跨服务共享的 ID 生成机制。仓库中的 data/guides/unique-id-generator.md 总结了社交类产品如 Facebook、Twitter、LinkedIn对 ID 的典型需求这正是绝大多数生产场景的通用清单全局唯一Globally unique任何时刻、任何节点生成的 ID 都不冲突按时间大致有序Roughly sorted by time方便按 ID 排序即按创建时间排序利于数据库索引与分页仅数字Numerical values only纯数字便于存储、比较与传输也便于作为主键与外部系统对接64 位64 bits主流语言与数据库的整型类型即可容纳存储紧凑高可扩展、低延迟Highly scalable, low latencyID 生成本身不能成为系统瓶颈不能引入明显延迟。围绕这五条需求业界演化出多种 ID 生成方案各有取舍。下面逐一展开仓库文档中介绍的 5 种方案。UUID最简单的客户端自生成方案UUIDUniversally Unique Identifier是一种标准化的 128 位标识符其核心价值在于不需要调用任何外部服务即可生成。工作原理UUID 通常由时间戳、节点标识如 MAC 地址或随机数与随机部分组合而成在客户端本地即可完成构造一次生成通常只需数微秒到数十微秒。优点生成逻辑极简单客户端本地即可完成无需网络调用、无需协调服务天然支持高并发生成能力只受限于客户端自身的 CPU在分布式环境下不需要任何全局协调器避免了单点问题。缺点原文档明确指出的三点不是顺序的not sequentialUUID 的随机性导致相邻生成的 ID 在数值上毫无规律无法满足“按时间大致有序”的需求对数据库索引不友好inefficient for database indexingB 树索引依赖有序插入来保持页面利用率随机主键会导致频繁的页分裂与随机写盘显著降低写入性能不保证全局唯一doesnt guarantee global uniqueness虽然 128 位空间巨大、碰撞概率极低但 UUID 生成不经过任何权威协调机构从理论上仍存在冲突风险原文档提醒“需要对 ID 冲突保持警惕尽管概率很小”。适用场景对排序不敏感、写入频率不高、或根本不需要主键具备时间语义的业务也常用于对象存储文件名、消息追踪 ID 等非核心主键场景。若业务明确要求 ID 单调有序且可排序则 UUID尤其 v4 随机版本不是首选。Snowflake时间戳 机器 ID 序列号Snowflake 是分布式 ID 生成中最经典、被引用最多的方案之一。原文档指出其生成过程由多个组件拼接而成时间戳timestamp、机器 IDmachine ID与序列号serial number。64 位二进制布局常见实现第 1 位为符号位固定为 0原文档特别强调这一点——“首位不使用以确保 ID 为正数positive IDs”即避免生成负数时间戳部分记录自某个自定义纪元epoch以来的毫秒数保证 ID 随时间增长、近似有序机器 ID 部分标识生成节点保证不同机器生成的 ID 不会撞车序列号部分在同一毫秒内自增解决单机高并发下的重复问题序列号用尽时通常等待下一毫秒。为什么说它“快且可扩展”原文档指出Snowflake 生成器无需通过网络与 ID 生成服务通信doesnt need to talk to an ID generator via the network——时间戳取自本地时钟机器 ID 在启动时配置序列号本地自增全部在单机内存中完成因此生成延迟极低且各节点完全并行扩展性天然很好。全局唯一性的实现变体原文档特别提示“Snowflake 的实现各不相同”。最典型的差异在于机器 ID 的取值策略如果只把机器 ID 当作单机房内的机器编号跨机房部署时仍可能冲突。为此可以将数据中心 IDdata center ID并入“MachineID”组件即用“机房编号 机架/机器编号”共同构成节点标识从而在物理上保证全局唯一。工程考量从源码结构推断的常见注意点Snowflake 依赖系统时钟若发生时钟回拨NTP 校准等可能出现重复或乱序 ID实现时通常需要记录上次生成时间戳并做回拨补偿同一毫秒内序列号耗尽时的等待策略、纪元起点选择等也会影响落地细节。适用场景对时间有序性有要求、需要高并发且希望避免中心化服务的高吞吐业务是最契合 data/guides/unique-id-generator.md 中五条需求的方案之一。数据库自增DB auto-increment简单但暴露信息数据库自增方案直接利用关系型数据库内置的AUTO_INCREMENT或等价的自增身份列能力。原文档强调了两点关键优势利用数据库的事务管理处理并发访问数据库本身通过内部锁/事务机制保证自增值在同一时刻只被一个请求消费开发者无需自行处理并发在单表内保证唯一同一张表内的自增 ID 不会重复唯一性由数据库强约束背书。但原文档也明确指出了该方案的两大代价涉及网络通信involves network communications每次取 ID 都是一次数据库往返在高并发下数据库容易成为热点瓶颈可能向外暴露敏感业务数据自增 ID 是连续的会让外部观察者推测业务规模。原文档给出了一个非常经典的例子——如果直接拿自增 ID 当用户 ID竞争对手就能大致估算出平台注册用户总数这在用户量属于核心商业机密的产品中是明显的信息泄露。适用场景单表单库、规模可控、无信息泄露顾虑的内部系统或作为号段方案见下的底层来源。对于面向公众、用户量敏感的高并发业务直接使用自增 ID 通常不推荐。数据库号段DB segment批量取号缓存于 ID 服务号段方案是数据库自增的改良版用于解决“每次取 ID 都要访问数据库”的性能痛点。原文档将其描述为从数据库中批量取回一批 ID 并缓存在 ID 服务ID servers中每个 ID 服务负责消费一个 ID 段segment。典型工作流程ID 服务启动或本地号段耗尽时向数据库申请一段连续 ID例如一次申请 1000 个数据库更新段的起点下一条记录的起始值返回[current, current step)区间ID 服务将整个段缓存在内存中后续请求直接从内存发号完全不再触碰数据库段内 ID 发完后再申请下一段。核心收益原文档强调“这极大地节省了数据库的 I/O 压力greatly saves the I/O pressure on the database”。假设每取 1000 个 ID 才访问一次数据库数据库访问量下降为原来的千分之一数据库不再成为发号瓶颈。常见工程增强属于该方案的标准实现细节多 ID 服务节点各持一段不同节点申请到互不重叠的号段天然实现水平扩展无需节点间通信双 buffer 预取一个号段即将耗尽时后台预先申请下一段避免发号毛刺段大小step调节段越大数据库压力越小但 ID 浪费跳号风险与内存占用越大需要根据并发量与业务容忍度权衡。适用场景需要高吞吐发号、又不希望引入额外中间件如 Redis的团队美团 Leaf-segment 等知名实现即属于这一类其价值在仓库文档中被概括为对数据库 I/O 压力的显著缓解。Redis基于内存的原子自增Redis 也可以作为分布式 ID 生成器。原文档给出的理由是Redis 以键值对key-value pair存储数据数据保存在内存中因此性能优于数据库方案。仓库中的 data/guides/how-can-redis-be-used.md 也把Global ID generator列为 Redis 的典型使用场景并说明“我们可以用 Redis 的整数类型Redis Int生成全局 ID”。实现方式利用 Redis 字符串类型的原子自增命令例如INCR unique_id:orders每次执行返回一个递增的唯一整数也可用INCRBY unique_id:orders 1000实现号段式的批量取号从而把每次请求数据库的压力进一步摊薄。为什么性能好Redis 的所有读写都在内存中完成原子自增操作在单线程事件循环下天然串行无需加锁即可保证并发安全data/guides/the-ultimate-redis-101.md 中也将INCR列为 Redis 最常用的基础命令之一并说明 Redis 提供亚毫秒级sub-millisecond延迟。工程考量Redis 是单点内存存储需要配合持久化RDB/AOF与高可用方案如主从、集群防止故障丢号或重建时的重复问题若对“按时间有序”有强需求单纯自增数字不携带时间信息需自行拼接例如“时间戳 Redis 自增序列”的组合或改用 Snowflake。适用场景团队已有 Redis 基础设施、需要高吞吐发号且能接受依赖中间件的场景是数据库号段方案之外最常见的内存型替代。五种方案横向对比与选型方案是否需网络/外部依赖是否按时间有序是否全局唯一性能主要风险UUID无需本地生成否随机无序概率性理论上可冲突高纯本地计算索引效率低、不满足排序需求Snowflake无需仅需配置机器 ID是时间戳驱动是机器 ID 区分节点可加数据中心 ID高本地拼装依赖系统时钟需防时钟回拨DB 自增每次取号访问数据库是单调递增单表内唯一中低受数据库吞吐限制暴露业务规模、数据库成热点DB 号段批量访问数据库是段内连续是段互不重叠高内存发号跳号浪费、需管理段与双 bufferRedis依赖 Redis 服务否纯自增是单实例原子自增高内存操作依赖中间件可用性需持久化与高可用总结如何为你的系统选择 ID 生成器回到 data/guides/unique-id-generator.md 提出的五条需求全局唯一、按时间有序、纯数字、64 位、高扩展低延迟可以得出清晰的选型脉络无需排序、本地优先→ UUID但注意其索引代价与概率性唯一要求时间有序、高并发、不想依赖中间件→ Snowflake注意时钟回拨与机器 ID 规划系统极小、信息不敏感→ 数据库自增简单直接高吞吐且已具备数据库基础设施→ 数据库号段显著缓解 I/O 压力高吞吐且已有 Redis 基础设施→ Redis 原子自增性能最佳但需保障可用性。没有银弹Snowflake 系方案在“有序 高性能 不依赖外部服务”上综合表现最好是系统设计面试与多数生产场景的首选UUID 与数据库自增适合轻量场景号段与 Redis 方案则是数据库与性能之间的经典折中。理解这五种方案的原理与取舍就掌握了分布式 ID 设计的最核心知识面。赞分享后端文档教程【免费下载链接】system-design-101Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.项目地址https://gitcode.com/GitHub_Trending/sy/system-design-101点击查看免费下载相关推荐System Design 101分布式系统核心原理深度解析System Design 101分布式系统核心原理深度解析 分布式系统是现代大型应用的基石它通过将计算任务分配到多台计算机上协同工作实现了高可用性、可扩后端文档教程Sonyflake分布式唯一ID生成器Sonyflake分布式唯一ID生成器 项目基础介绍和主要编程语言 Sonyflake 是一个受 Twitter Snowflake 启发的分布式唯一 IDChameleonUltra安全研究如何利用Crypto1算法漏洞进行MIFARE卡破解ChameleonUltra安全研究如何利用Crypto1算法漏洞进行MIFARE卡破解 什么是ChameleonUltra ChameleonUltra是创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表