唯一ID生成器设计方案

news2025/4/9 19:26:35

《亿级流量系统架构设计与实战》总结

1. 唯一ID的核心需求

全局唯一性:分布式系统中所有节点生成的ID不可重复。
趋势递增性(可选):ID按时间或序列递增,优化数据库写入性能。
高可用性:服务需7×24小时可用,支持故障自动恢复。
高性能:单节点QPS需达到数万至百万级别。
可扩展性:支持水平扩展以应对业务增长。


2. 单机递增方案
2.1 Redis INCR命令

原理:利用Redis原子操作INCRINCRBY生成单调递增ID。
实现

# 生成ID
redis-cli INCR my_counter

技术细节
集群模式:通过Redis Cluster分片存储多个计数器(如user_id:1, order_id:2)。
持久化:开启AOF或RDB确保重启后ID不丢失。
优点:简单高效,延迟低(毫秒级)。
缺点
• 依赖Redis集群,增加系统复杂度。
• 高并发下可能成为瓶颈(需维护长连接池)。
适用场景:低并发系统或作为其他方案的兜底。


2.2 数据库自增主键

原理:利用关系型数据库(如MySQL)的自增主键特性。
实现

ALTER TABLE user AUTO_INCREMENT = 1000;
INSERT INTO user (name) VALUES ('Alice');

技术细节
分库分表友好性:可通过MOD运算拆分表(如user_id % 1024)。
主从延迟:主从同步可能导致短暂ID不连续。
优点:绝对有序,天然事务支持。
缺点
• 扩展性差,需预分配ID段或频繁修改表结构。
• 高并发写入易成为性能瓶颈。
适用场景:传统单体应用或低并发场景。


3. 分布式递增方案
3.1 Snowflake算法

核心组成

long id = ((timestamp - twepoch) << timestampLeftOffset) 
          | (datacenterId << datacenterIdShift)
          | (machineId << machineIdShift)
          | sequence;

参数说明
timestamp:毫秒级时间戳(41位,支持约69年)。
datacenterId:数据中心ID(5位,支持32个机房)。
machineId:工作机器ID(5位,支持32台机器)。
sequence:序列号(12位,同一毫秒内支持4096个ID)。
技术实现
时钟回拨问题:记录历史时间戳,若发生回拨则抛出异常等待时钟同步。
位分配优化:根据业务需求调整各字段位数(如延长timestamp到42位)。
优点
• 分布式生成,性能高(单机QPS可达百万)。
• ID趋势递增,利于数据库写入。
缺点
• 依赖机器时钟,时钟回拨可能导致ID重复。
• 需手动分配datacenterIdmachineId
适用场景:高并发、需趋势递增的场景(如订单号、消息ID)。


3.2 Leaf(美团分布式ID生成服务)

Leaf-segment方案
原理:预分配ID号段(如1000~1999),客户端批量拉取号段。
架构
Client → Leaf Server(号段分配) → DB(存储号段状态)
优化:支持号段预加载(如提前拉取下一个号段)。

Leaf-snowflake方案
原理:基于Snowflake算法,通过ZooKeeper选举Master节点分配machineId
架构
Client → Leaf Server(Snowflake节点) ← ZooKeeper(协调)
技术细节
号段分配:支持号段长度动态调整(如从1000调整为10000)。
时钟回拨检测:Leaf-snowflake集成Snowflake的时钟回拨处理逻辑。
优点
• 高可用,支持号段和Snowflake双模式切换。
• 支持号段/雪花模式混合部署。
缺点
• 依赖外部存储(如DB/ZooKeeper)。
• 需部署中间件服务。
适用场景:中大规模分布式系统,需兼顾灵活性和高可用性。


4. 其他方案
4.1 UUID

原理:基于MAC地址、时间戳和随机数生成128位唯一标识。
实现

UUID.randomUUID().toString() // 输出类似 "123e4567-e89b-12d3-a456-426614174000"

优点:本地生成,无依赖。
缺点
• 无序导致数据库索引性能下降。
• 存储空间大(16字节)。
适用场景:离线系统或对顺序无要求的场景。

4.2 Redis Hash/Redisson

原理:利用Redis的Hash数据结构生成ID。
实现

HSET my_hash field 1
HINCRBY my_hash field 1

优点:支持原子递增,可扩展多个Hash实例。
缺点:需维护Redis集群,性能低于原生INCR。


5. 方案对比与选型建议
方案全局唯一性趋势递增性能复杂度适用场景
Redis INCR✔️✔️低并发系统
数据库自增✔️✔️传统单体应用
Snowflake✔️✔️极高高并发、需趋势递增的场景
Leaf-segment✔️中大规模分布式系统
Leaf-snowflake✔️✔️极高需混合部署的复杂系统

6. 架构图示
6.1 Snowflake算法架构
Client → Time Service(获取时间戳)
       ↓
     Machine ID(通过配置或ZooKeeper分配)
       ↓
 Sequence Generator(本地计数器)
       ↓
ID合成器 → [timestamp << 22] | [machineId << 17] | [sequence]
6.2 Leaf分布式服务架构
Client → Leaf Client SDK → Leaf Server(HTTP/RPC接口)
       ↑                    ↓
       └─── ZooKeeper(协调Master选举) ────┘

7. 最佳实践
  1. 时钟回拨防御
    • 记录历史时间戳,若检测到回拨则抛出异常等待时钟同步。
    • 使用NTP服务校准时钟,减少回拨概率。
  2. 分库分表友好
    • ID高位分配分片字段(如末尾N位表示分片号)。
  3. 预生成ID池
    • 对高并发场景预加载ID池(如提前生成10万ID缓存在本地)。

通过以上方案对比和技术实现细节,可根据业务场景选择最适合的唯一ID生成策略。对于大多数互联网业务,推荐使用Leaf-snowflake或Snowflake算法,兼顾性能与可用性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2329787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在 Ubuntu24.04 LTS 上 Docker Compose 部署基于 Dify 重构二开的开源项目 Dify-Plus

一、安装环境信息说明 硬件资源&#xff08;GB 和 GiB 的主要区别在于它们的换算基数不同&#xff0c;GB 使用十进制&#xff0c;GiB 使用二进制&#xff0c;导致相同数值下 GiB 表示的容量略大于 GB&#xff1b;换算关系&#xff1a;1 GiB ≈ 1.07374 GB &#xff1b;1 GB ≈ …

NO.64十六届蓝桥杯备战|基础算法-简单贪心|货仓选址|最大子段和|纪念品分组|排座椅|矩阵消除(C++)

贪⼼算法是两极分化很严重的算法。简单的问题会让你觉得理所应当&#xff0c;难⼀点的问题会让你怀疑⼈⽣ 什么是贪⼼算法&#xff1f; 贪⼼算法&#xff0c;或者说是贪⼼策略&#xff1a;企图⽤局部最优找出全局最优。 把解决问题的过程分成若⼲步&#xff1b;解决每⼀步时…

瑞萨RA4M2使用心得-KEIL5的第一次编译

目录 前言 环境&#xff1a; 开发板&#xff1a;RA-Eco-RA4M2-100PIN-V1.0 IDE&#xff1a;keil5.35 一、软件的下载 编辑瑞萨的芯片&#xff0c;除了keil5 外还需要一个软件&#xff1a;RASC 路径&#xff1a;Releases renesas/fsp (github.com) 向下找到&#xff1a; …

数据分析-Excel-学习笔记

Day1 复现报表聚合函数&#xff1a;日期联动快速定位区域SUMIF函数SUMIFS函数环比、同比计算IFERROR函数混合引用单元格格式总结汇报 拿到一个Excel表格&#xff0c;首先要看这个表格个构成&#xff08;包含了哪些数据&#xff09;&#xff0c;几行几列&#xff0c;每一列的名称…

整车CAN网络和CANoe

车载网络中主要包含有Can网络,Lin网络,FlexRay,Most,以太网。 500kbps:500波特率,表示的数据传输的速度。表示的是最大的网速传输速度。也就是每秒 500kb BodyCan车身Can InfoCan娱乐信息Can 车身CAN主要连接的是ESB电动安全带 ADB自适应远光灯等 PTCan动力Can 底盘Can

ChatGPT 的新图像生成器非常擅长伪造收据

本月&#xff0c;ChatGPT 推出了一种新的图像生成器&#xff0c;作为其 4o 模型的一部分&#xff0c;该模型在生成图像内的文本方面做得更好。 人们已经在利用它来生成假的餐厅收据&#xff0c;这可能会为欺诈者使用的已经很广泛的 AI 深度伪造工具包添加另一种工具。 多产的…

JS页面尺寸事件

元素位置 在这里插入图片描述 父元素带有定位时输出相对于父亲元素的距离值

网络协议之基础介绍

写在前面 本文看下网络协议相关基础内容。 1&#xff1a;为什么要有网络协议 为了实现世界各地的不同主机的互联互通。 2&#xff1a;协议的三要素 协议存在的目的就是立规矩&#xff0c;无规矩不成方圆嘛&#xff01;但是这个规矩也不是想怎么立就怎么立的&#xff0c;也…

初识数据结构——Java集合框架解析:List与ArrayList的完美结合

&#x1f4da; Java集合框架解析&#xff1a;List与ArrayList的完美结合 &#x1f31f; 前言&#xff1a;为什么我们需要List和ArrayList&#xff1f; 在日常开发中&#xff0c;我们经常需要处理一组数据。想象一下&#xff0c;如果你要管理一个班级的学生名单&#xff0c;或…

uniapp微信小程序引入vant组件库

1、首先要有uniapp项目&#xff0c;根据vant官方文档使用yarn或npm安装依赖&#xff1a; 1、 yarn init 或 npm init2、 # 通过 npm 安装npm i vant/weapp -S --production# 通过 yarn 安装yarn add vant/weapp --production# 安装 0.x 版本npm i vant-weapp -S --production …

贪心进阶学习笔记

反悔贪心 贪心是指直接选择局部最优解&#xff0c;不需要考虑之后的影响。 而反悔贪心是在贪心上面加了一个“反悔”的操作&#xff0c;于是又可以撤销之前的“鲁莽行动”&#xff0c;让整个的选择稍微变得“理智一些”。 于是&#xff0c;我个人理解&#xff0c;反悔贪心是…

Java 大视界 -- Java 大数据在航天遥测数据分析中的技术突破与应用(177)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

架构师面试(二十七):单链表

问题 今天的问题对于架构师来说会相对容易许多。今天出一个【数据结构与算法】相关的题目&#xff0c;醒醒脑。 给一张【单链表】&#xff0c;该单链表有100个节点元素&#xff08;当然&#xff0c;事先我们是不知道100这个数目的&#xff09;&#xff0c;要获取倒数第8个元素…

从扩展黎曼泽塔函数构造物质和时空的结构-15

回来考虑泽塔函数&#xff0c; 我们知道&#xff0c; 也就是在平面直角坐标系上反正切函数在x上的变化率&#xff0c;那么不难看出&#xff0c; 就是在s维空间上的“广义”反正切函数在单位p上的变化率&#xff0c;而泽塔函数&#xff0c;就是这些变化率的全乘积&#xff0c; 因…

01背包问题详解 具体样例模拟版

01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 v i v_i vi​&#xff0c;价值是 w i w_i wi​。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 …

网络初识 - Java

网络发展史&#xff1a; 单机时代&#xff08;独立模式&#xff09; -> 局域网时代 -> 广域网时代 -> 移动互联网时代 网络互联&#xff1a;将多台计算机链接再一起&#xff0c;完成数据共享。 数据共享的本质是网络数据传输&#xff0c;即计算机之间通过网络来传输数…

每日一题(小白)回溯篇4

深度优先搜索题&#xff1a;找到最长的路径&#xff0c;计算这样的路径有多少条&#xff08;使用回溯&#xff09; 分析题意可以得知&#xff0c;每次向前后左右走一步&#xff0c;直至走完16步就算一条走通路径。要求条件是不能超出4*4的范围&#xff0c;不能重复之前的路径。…

k8s进阶之路:本地集群环境搭建

概述 文章将带领大家搭建一个 master 节点&#xff0c;两个 node 节点的 k8s 集群&#xff0c;容器基于 docker&#xff0c;k8s 版本 v1.32。 一、系统安装 安装之前请大家使用虚拟机将 ubuntu24.04 系统安装完毕&#xff0c;我是基于 mac m1 的系统进行安装的&#xff0c;所…

C++ STL 详解 ——list 的深度解析与实践指南

在 C 的标准模板库&#xff08;STL&#xff09;中&#xff0c;list作为一种重要的序列式容器&#xff0c;以其独特的双向链表结构和丰富的操作功能&#xff0c;在许多编程场景下发挥着关键作用。深入理解list的特性与使用方法&#xff0c;能帮助开发者编写出更高效、灵活的代码…

按键切换LCD显示后,显示总在第二阶段,而不在第一阶段的问题

这是一个密码锁的程序&#xff0c;当在输入密码后&#xff0c;原本是要重置密码&#xff0c;但是程序总是在输入密码正确后总是跳转置设置第二个密码&#xff0c;而第一个密码总是跳过。 不断修改后&#xff0c; 解决方法 将if语句换成switch语句&#xff0c;这样就可以分离程序…