如何在分布式场景下生成全局唯一 ID ?

游戏后台生成唯一ID MMO游戏后台生成唯一ID   MMO游戏后台通常需要由大量服务器来共同承载海量玩家,虽然玩家可能分布在不同的游戏大区,但是他们可能会通过跨服等等方式进行各种交互。游戏中的角色,装备,物品等需要生成一个全局唯一ID标识,便于辨别不同玩家,不同装备,也方便定位外网问题。   常见的分布式全局唯一ID生成方式包括使用数据库自增,使用Redis的原子操作INCR和INCRBY,使用UUID,SnowFl... 阅读详情

在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或者用作事务版本号、分布式链路追踪等等,好的全局唯一 ID 需要具备这些特点:

  • 全局唯一:这是最基本的要求,不能重复;
  • 递增:有些特殊场景是必须递增的,比如事务版本号,后面生成的 ID 一定要大于前面的 ID ;有些场景递增比不递增要好,因为递增有利于数据库索引的性能;
  • 高可用:如果是生成唯一 ID 的系统或服务,那么一定会有大量的调用,那么保证其高可用就非常关键了;
  • 信息安全:如果 ID 是连续的,那么很容易被恶意操作或泄密,比如订单号是连续的,那么很容易就被看出来一天的单量大概是多少;
  • 另外考虑到存储压力,ID 当然是越短越好。

那么分布式场景下有哪些生成唯一 ID 的方案呢?

利用数据库生成

先说最容易理解的方案,利用数据库的自增长序列生成:数据库生成唯一主键,并通过服务提供给其他系统;如果是小型系统,数据总量和并发量都不是很大的情况下,这种方案足够支撑。

如果每次生成一个 ID 可能会对数据库有压力,可以考虑一次性生成 N 个 ID 放入缓存中,如果缓存中的 ID 被取光,再通过数据库生成下一批 ID 。

  • 优点: 理解起来最容易,实现起来也最简单。
  • 缺点: 也非常明显了,每种数据库的实现不同,如果数据库需要迁移的话比较麻烦;最大的问题是性能问题,并发量到一定级别的时候这个方法估计会很难满足性能需求;另外通过数据库自增生成的 ID 携带的信息太少,只能起到一个标识的作用,同时自增 ID 也是连续的。

利用其他组件/软件/中间件生成

利用 Redis / MongoDB / zookeeper 生成:Redis 利用 incr 和 increby ;MongoDB 的 ObjectId;zk 通过 znode 数据版本;都可以生成全局的唯一标识码。

我们用 MongoDB 的 ObjectId 来举例:

{"_id": ObjectId("5d47ca7528021724ac19f745")}

MongoDB 的 ObjectId 共占 12 个字节,其中:

  • 3.2 之前的版本(包括 3.2): 4 字节时间戳 + 3 字节机器标识符 + 2 字节进程 ID + 3字节随机计数器
  • 3.2 之后版本: 4 字节时间戳 + 5 字节随机值 + 3 字节递增计数器

不管是老版本还是新版本,MongoDB 的 ObjectId 至少都可以保证集群内的唯一,我们可以搭建一个全局唯一 ID 生成的服务,利用 MongoDB 生成 ObjectId 并对外提供服务(MongoDB 的各语言驱动都实现了 ObjectId 的生成算法)。

  • 优点: 性能高于数据库;可以使用集群部署;ID 内自带一些含义,比如时间戳;
  • 缺点: 和数据库一样,需要引入对应的组件/软件,增加了系统的复杂度;最关键的是,这两种方案都意味着生成全局唯一 ID 的系统(服务),会成为一个单点,在软件架构中,单独就意味着风险;如果这个服务出现问题,那么所有依赖于这个服务的系统都会崩溃掉。

UUID

这个是分布式架构中,生成唯一标识码最常用的算法。为了保证 UUID 的唯一性,生成因素包括了MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素;UUID 有多个版本,每个版本的算法不同,应用范围也不同:

  • Version 1: 基于时间的 UUID,是通过时间戳 + 随机数 + MAC地址得到;如果应用直接局域网内使用,可以使用 IP 地址替代 MAC 地址;高度唯一(MAC 地址泄漏,也是一个安全问题)。
  • Version 2: DCE 安全的 UUID,把 Version 1 中的时间戳前 4 位置换为 POSIX 的 UID 或 GID ;高度唯一。
  • Version 3: 基于名字的 UUID(MD5),通过计算名字和名字空间的 MD5 散列值得到;一定范围内唯一。
  • Version 4: 随机 UUID,根据随机数或伪随机数生成 UUID;有一定概率重复。
  • Version 5: 基于名字的UUID(SHA1),和 Version 3 类似,只是散列值计算使用SHA1算法;一定范围内唯一。
public class CreateUUID {
 public static void main(String[] args) {
  String uuid = UUID.randomUUID().toString();
  System.out.println("uuid : " + uuid);
​
  uuid = UUID.randomUUID().toString().replaceAll("-","");
  System.out.println("uuid : " + uuid);
 }
}
  • 优点: 本地生成,没有网络消耗,不需要第三方组件(也就没有单点的风险),生成比较简单,性能好。
  • 缺点: 长度长,不利于存储,并且没有排序,相对来说还会影响性能(比如 MySQL 的 InnoDB 引擎,如果 UUID 作为数据库主键,其无序性会导致数据位置频繁变动)。

Snowflake

如果希望 ID 可以本地生成,但是又不要和 UUID 那样无序,可以考虑使用 Snowflake 算法(Twitter开源)。

SnowFlake 算法生成 ID 是一个 64 bit 的整数,包括:

  • 1 bit : 不使用,固定是 0 ;
  • 41 bit : 时间戳(毫秒),数值范围是:0 至 2的41次方 - 1 ;转换成年的话,大约是 69 年;
  • 10 bit : 机器 ID ;5 位机房 ID + 5 位机器 ID ;(服务集群数量比较小的时候,可以手动配置,服务规模大的话,可以采用第三方组件进行自动配置,比如美团的 Leaf-snowflake,就是通过 Zookeeper 的持久顺序节点做为机器 ID)
  • 12 bit : 序列号,用来记录同一个毫秒内生成的不同 ID 。

在Java中,SnowFlake 算法生成的 ID 正好可以用 long 来进行存储。

  • 优点: 本地生成,没有网络消耗,不需要第三方组件(也就没有单点的风险),一定范围内唯一(基本可以满足大部分场景),性能好,按时间戳递增(趋势递增);
  • 缺点: 依赖于机器时钟,同一台机器如果把时间回拨,生成的 ID 就会有重复的风险。

image

此外,还有很多优秀的互联网公司也提供了唯一 ID 生成的方案或框架,比如美团开源的 Leaf ,百度开源的 UidGenerator 等等。

@Resource
private UidGenerator uidGenerator;
​
@Test
public void testSerialGenerate() {
    // Generate UID
    long uid = uidGenerator.getUID();
    System.out.println(uidGenerator.parseUID(uid));
}

会点代码的大叔 | 文【原创】


敬请关注会点代码的大叔

电磁波函数复数表示法:为什么物理学家偏爱e^(ikz)而非cos(kr-wt)? 本文深入解析了电磁波函数复数表示法(如e^(ikz))相较于传统余弦形式的巨大优势。通过欧拉公式,复数形式将复杂的三角运算转化为简洁的指数运算,在微分、积分、线性叠加及处理相位时展现出极高的计算效率,是物理学家和工程师分析波动现象的核心工具。 阅读详情

相关推荐

Python自动化批量识别化学分子结构——从图片到SMILES/SDF的实战指南

本文提供了使用Python自动化批量识别化学分子结构图片的实战指南。详细对比了基于Molvec API的在线快速方案与本地部署OSRA工具的两种路径,包含完整的代码示例、环境配置及优化技巧,帮助化学研究者高效地将图片批量转换为SMILES或SDF格式,显著提升数据处理效率。

apple5的专栏 946

分布式系统全局唯一ID的几种实现方式

现如今可谓是微服务、分布式、IoT(物联网)横行的时代,作为一名开发者始终还是要保持一定的危机意识,特别是在日常的项目开发中,若是有机会接触到一些关于微服务、分布式下的应用场景,应当硬着头皮、排除万难,主动应承下来上去大干一场;这期间不管结果如何,积累下来的经验将会让自己受益匪浅;而本文要介绍的“分布式全局唯一ID”便是一种典型的分布式应用场景!!! 话不多说,咱们直接进入正题~~~ 说起这个全局唯一ID,你可能会第一时间想到“数据库的自增主键”、“UUID”、“雪花算法”等等,更有甚者,还能说出一些大厂开

qq_43842093的博客 3147

分布式全局唯一ID解决方案详解

分布式

qq_23350817的博客 989

全球第一开源云ERP Odoo操作手册 模块安装和界面汉化指南

Odoo 的功能包含在不同的模块中, 刚创建的数据库除 Odoo 的核心模块外, 其它模块并没有被安装到系统中,你可以根据需要安装它们。本节将介绍安装模块和界面汉化的相关知识。

weixin_44793763的博客 2075

【Sentaurus TCAD仿真】几种基础操作

当内存不足时,没必要删除整个Project,只需要 Clean up 节点信息即可。因为占用内存的主要部分是。文件数据,Command文件是不占用多少内存的,下次需要此工程仿真结果重新运行即可。右击可以对该工程进行剪切、复制、删除、重命名等操作。当节点号有时候排序混乱的时候,我们需要重新编排节点号。此时左侧工具栏就能看见我们新建的这个工程。运行节点时不同的颜色代表目前的状态。在这个地方添加要使用的工具。这个时候需要的工具就建好了。然后选择需要使用的工具。我们需要保存这个工程。

qq_45746744的博客 1万+

【分布式】分布式唯一 ID 的 几种生成方案以及优缺点&snowflake优化方案

日常开发中,我们需要对系统中的各种数据使用 ID 唯一表示,比如 用户 ID 对应且仅对应一个人,商品 ID 对应且仅对应一件商品,订 单 ID 对应且仅对应一个订单。拿MySQL数据库举个例子:在我们业务数据量不大的时候,单库单表完全可以支撑现有业务,数据再大一点搞个MySQL主从同步读写分离也能对付。但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;

Alex的博客 3266

YOLOv8改进 | Conv篇 | 轻量级下采样方法ContextGuided(大幅度涨点)

ContextGuided通过创新的局部-全局协同机制,解决了传统下采样方法中细节丢失与上下文缺失的核心痛点。实验证明其在YOLOv8上可实现最高2.6%的mAP提升,且计算开销增加不足5%。这种即插即用的设计为实时目标检测系统提供了新的优化方向。创新启示:轻量化不代表简单裁剪,智能信息融合才是未来方向!下一步探索与Transformer结合构建混合架构多尺度上下文融合机制3D点云中的扩展应用资源获取完整训练代码:[GitHub链接]预训练模型:[Google Drive链接]讨论话题。

QQ_778132974的博客 289

分布式ID(唯一id-详解及教程)

应用场景 在业务系统中很多场景下需要生成不重复的 ID,比如京东订单编号、飞机票订单号、外卖订单号、支付流水单号、优惠券编号等都需要使用到。账户进行标识,以一个有意义的有序的序列号来作为全局唯一的ID。如电商平台,为了保证(用户信息安全),可通过订单编号查询到:商家信息、买家信息、物流信息、等关联全部信息。 分布式ID特点 分布式系统中我们对ID生成器要求又有哪些呢? 1. 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。 2. 简洁/直观:(生成的ID号)客户用于关联其它

wenkezhuangyuan的博客 2234

【AVRCP】规范精讲[19]: 媒体属性全解析,让你的蓝牙设备显示完整歌曲信息

AVRCP协议中的媒体属性是蓝牙音频设备传输歌曲元数据的关键,包含标题、艺术家、专辑等32位ID标识的键值对信息。规范要求字符串属性必须使用UTF-8编码,但乱码问题频发(如中文显示异常),主因是设备未遵循编码标准或使用GBK等非规范格式。常见问题包括信息不全(仅显示标题)、封面缺失(因带宽限制或格式不支持)及更新延迟(通知机制未启用)。解决方案包括强制UTF-8编码、优化封面大小(如300x300像素JPEG)、主动请求缺失属性。Android示例代码展示了通过广播接收器解析媒体属性的方法。

byte轻骑兵的技术小窝 1万+

MTK-Android12开机应用自启需求-自定义原生Launcher3 主界面布局图标

MTK平台 Android12 版本 上实现 开机应用自启需求-自定义原生Launcher3 主界面布局图标。添加一个属性定义即可,如下:这里自定义一个属性目的是为了在加载Launcher3启动时候从属性获取需要自启动应用的包名,可以扩展动态替换 自启动包名。这里有两种方案,要么在Launcher3里面实现,要么在系统服务里面在开机时候启动第三方一次。这里强烈建议在Launcher3中去实现,体验效果更好。// 第一步:定义属性,// 第二步:在onCreate 方法中获取属性并启动应用。

十年饮冰,难凉热血 1378

分布式系统全局唯一ID简介、特点、生成

一、什么是分布式系统唯一ID 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。 如在金融、电商、支付、等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数据库的自增ID显然不能满足需求,此时一个能够生成全局唯一ID的系统是非常必要的。 二、分布式系统唯一ID的特点 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。 趋势递增:在M...

cowbin2012的专栏 1万+

YOLO26 改进 | (教师:YOLOv8L,学生:YOLO26) | 知识蒸馏 (Knowledge Distillation)

本文介绍了基于YOLO26框架的知识蒸馏实战方法,通过教师模型指导学生模型训练,在不增加推理成本的情况下提升模型精度。文章详细阐述了基于响应的知识蒸馏实现方案,通过最小化教师与学生模型预测Logits间的KL散度实现知识迁移。核心实现包括:1) 创建DistillationModel包装器类,同时运行师生模型;2) 自定义DistillationLoss,在原检测损失基础上增加KL散度损失。该方法适用于希望保持YOLO26轻量级特性同时获得接近大模型精度的场景,文中提供了完整的代码实现方案。

weixin_51988935的博客 510

面试官问:高并发场景下,如何保证全局唯一分布式ID生成?

前言 系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。 这篇文章就是给各位看官提供一个生成分布式唯一全局id生成方案的思路,希望能帮助到大家。 不足之处,请多多指教!! 问题 为什么需要分布式全局唯一ID以及分布式ID的业务需求 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识,如在美团点评的金融、支付、餐饮、酒店 猫眼电影等产品的系统中数据逐渐增长,对数据库分库分表后需要有一个唯一ID来标识一条数据或信息; 特别Ian的订单、骑手、优惠券都需要有唯一ID做标识 此

jvm77625的博客 412

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

分布式场景全局唯一ID生成工具类(非雪花算法)

这是一个分布式场景下全局唯一ID生成工具,类似于雪花算法(SnowFlake)。如果你需要生成订单号等类似前缀+yyMMddHHmmss+序列格式的全局唯一性序列可以使用。 结构 {前缀}{yyMMddHHmmss}{workerId}{序列ID} 优点 与雪花算法一样,单机执行无需其他中间件做分布式协调 代码简单,可自行修改。雪花算法估计很多人还看不太明白吧 局限性 需要提前规划序号的最大值,最大值 > 预计单机一秒钟需要生成的序列最大值 最佳实践 通过ZK等维护WORKER_ID这样可以更

vakinge在路上 549

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

微信用户全局唯一标识_如何在分布式场景下生成全局唯一 ID?

[ 擅编码,懂调优,会架构,用大白话讲解复杂的技术 ]在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或者用作事务版本号、分布式链路追踪等等,好的全局唯一 ID 需要具备这些特点:全局唯一:这是最基本的要求,不能重复;递增:有些特殊场景是必须递增的,比如事务版本号,后面生成的 ID 一定要大于前面...

weixin_39573136的博客 492

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

c语言连续生成多个随机数_如何在分布式场景下生成全局唯一 ID?

[ 擅编码,懂调优,会架构,用大白话讲解复杂的技术 ]在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或者用作事务版本号、分布式链路追踪等等,好的全局唯一 ID 需要具备这些特点:全局唯一:这是最基本的要求,不能重复;递增:有些特殊场景是必须递增的,比如事务版本号,后面生成的 ID 一定要大于前面...

weixin_39872044的博客 420

【283期】面试官问:高并发场景下,如何保证全局唯一分布式 ID 生成?

点击上方“Java精选”,选择“设为星标”别问别人为什么,多问自己凭什么!下方有惊喜,留言必回,有问必答!每一天进步一点点,是成功的开始...前言系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。这篇文章就是给各位看官提供一个生成分布式唯一全局id生成方案的思路,希望能帮助到大家。不足之处,请多多指教!!问题为什么需要分布式全局唯一ID以及分...

Java精选 381

MySQL Sequence实战:构建分布式场景下的全局唯一ID生成器

本文详细探讨了MySQL Sequence在分布式系统中作为全局唯一ID生成器的实战应用。通过对比自增主键与Sequence的本质区别,提供完整的表结构设计和核心函数实现方案,并分享高并发优化技巧与Spring Boot集成方法。文章特别强调Sequence在保证唯一性、趋势递增和高可用性方面的优势,实测QPS可达5000+,是分布式环境下ID生成的理想解决方案。

weixin_27032989的博客 389

微信用户全局唯一标识_【融云分析】如何实现分布式场景下唯一 ID 生成?

◀背景▶对于一套分布式部署的 IM 系统,要求每条消息的 ID 要保证在集群中全局唯一且按生成时间有序排列。如何快速高效的生成消息数据的唯一 ID ,是影响系统吞吐量的关键因素。那么,融云是如何做到生成全局唯一消息 ID 的呢?首先需要明确下 ID 生成的核心需求:1. 全局唯一2. 有序◀设计▶融云消息数据的唯一 ID 长度采用 80 Bit 。每 5 个 Bit ,进行一次 32 进制编码,转...

weixin_32894769的博客 293

c语言连续生成不同随机数_面试官:如何在分布式场景下生成全局唯一 ID?

在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或者用作事务版本号、分布式链路追踪等等,好的全局唯一 ID 需要具备这些特点:全局唯一:这是最基本的要求,不能重复;递增:有些特殊场景是必须递增的,比如事务版本号,后面生成的 ID 一定要大于前面的 ID ;有些场景递增比不递增要好,因为递增有利于数...

weixin_36074800的博客 202

分布式 ID

唯一 ID(Unique Identifier)是指在计算机系统中能够唯一标识某个实体的字符串或数字。在分布式系统中,这种标识符被称为分布式 ID,它需要在整个系统范围内保持唯一性。

Made In SQL 1093

分布式全局唯一ID生成器(支持多种注册中心)的实现

在订单、支付的业务场景中,单号的生成规则与生成方式十分重要,实现有很多种,最简单的是基于mysql自增主键实现,方案优劣不多说,大家都清楚。我们今天实现一种分布式的、可扩展的并且在高并发场景能保证高性能的全局唯一ID生成方案(基于twitter的snowflake原理进行改编和扩展)。不多说直接上代码。 package com.zxm.adapter; import org.apache.z...

明教三十四代觉主的博客 6万+

.NET集成DeveloperSharp生成分布式唯一ID

在某个大型电商系统A中,“订单”这类大数据(比如,每天产生1500万条订单)必定不会存储在1台数据库服务器中,而是分布式的存储在多台数据库服务器组成的一个集群中(比如,1000台数据库服务器组成一个集群)。若此时,另外一家公司的电商系统B,要与你家的电商系统A合并(甚至还有更多公司的C、D、E、等等),那么这些系统合并时“订单Id”出现重复的概率是很大的。经验:其实,无论是单机小型应用,还是多机大型分布式应用,从今天开始,你都应采用“分布式唯一Id”作为数据库中、每个表的“主键”。//产生分布式唯一Id。

.Net技术、软件架构、人工智能、数字化转型、DeveloperSharp、微服务、工业互联网、智能制造 1722
上一篇: 用了强大的 Redis,我们的项目是不是不再惧怕高并发查询了?缓存穿透和缓存雪崩了解一下。
下一篇: 明白了缓存穿透和缓存雪崩,再了解一下缓存击穿!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值