分布式全局唯一ID生成策略

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: “唯一ID”在应用程序中是一个很常见的需求,它用于唯一标识一个业务对象、一个资源、或者一个消息等等。在数据库中,唯一ID一般是用来做为一个数据的主键。看过前面介绍MySQL索引原理的文章的朋友应该知道,主键对于数据库的重要性不言而喻。在单机场景下,要得到一个全局唯一的ID是非常容易的,你可以使用数据库的自增功能。

“唯一ID”在应用程序中是一个很常见的需求,它用于唯一标识一个业务对象、一个资源、或者一个消息等等。在数据库中,唯一ID一般是用来做为一个数据的主键。看过前面介绍MySQL索引原理的文章的朋友应该知道,主键对于数据库的重要性不言而喻。

在单机场景下,要得到一个全局唯一的ID是非常容易的,你可以使用数据库的自增功能


但是如果在分布式的场景下,想要构建构建一个全局唯一的ID就有些不一样。因为分布式系统一般是高并发场景,那自然不适合使用单机数据库的自增功能了。如果你的技术选型恰好是MySQL这样的“非分布式数据库”,那就得参考一下业界常见的分布式全局唯一ID生成策略了。


UUID

UUID全称是Universally Unique Identifier,翻译过来叫通用唯一识别码。标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:9628f6e9-70ca-45aa-9f7c-77afe0d26e05,到目前为止业界一共有5种方式生成UUID,详情见IETF发布的UUID规范《A Universally Unique IDentifier (UUID) URN Namespace》,分别称为UUID的5个版本。

在JDK自带的UUID类可以产生版本3和版本4的UUID。所以这里简单介绍一下版本3和版本4的UUID的生成方式。

  • UUID版本3:通过计算name和namespace的MD5散列值得到。
  • UUID版本4:根据随机数,或者伪随机数生成UUID。这种UUID产生重复的概率是可以计算出来的,但是重复的可能性可以忽略不计,因此该版本也是被经常使用的版本。

也有在线生成UUID的网站,如果你的项目上用到了UUID,可以用来生成临时的测试数据。www.uuidgenerator.net/

UUID的优势是实现起来很简单,用JDK原生的API即可得到。劣势是与基于b-Tree引擎的数据库的主键索引策略不太符合,不适合作为高性能需求的场景下的数据库主键。


基于Redis实现

都用分布式了,多半要上个缓存。用缓存的话,可能会使用Redis。Redis的INCR函数在单机上是原子操作,可以保证唯一且递增。

单机Redis可能无法支撑高并发。而如果使用Redis集群,如何保证ID的唯一性呢?可以使用步长的方式。比如有5个Redis节点组成的集群,它们生成的ID分别为:

A: 1,6,11,16,21

B: 2,7,12,17,22

C: 3,8,13,18,23

D: 4,9,14,19,24

E: 5,10,15,20,25


类snowflake方案

Twitter利用Zookeeper实现了一个全局ID生成的服务snowflake。其生成ID的数据结构如下图所示:

共64位,正好对应Java中的long型,第一个符号位不用,然后41位用于表示时间戳。后续10位用来表示节点的id,如果是多机房节点,可以划分前5位用来表示机房id,后5位用来表示每个机房下的机器的id。最后12位用来表示序列号,这样可以做到同一毫秒,同一机器生成多个id,12位算下来最多支持4096个。

这里的时间戳并不是当前时间的Time Stamp,而是当前时间相对于起始时间的差值。如果基于毫秒来计算的话,41位大约可以用69年。

snowflake算法有许多变种。可以根据自己的实际情况调整位数的分配,比如时间戳占42位,机器id占9位。42位时间戳就可以用138年等。

百度的UidGenerator和美团的Leaf都是基于snowflake的变种。

snowflake是一种比较好的生成ID方式,保证全局唯一,且支持高并发。而且是long类型的,趋势递增,可以用于数据库主键。还可以根据时间来排序。

但也有其缺点,就是强依赖服务器的时钟,如果服务器的时钟出现回拨(比如闰秒或者NTP同步),就会导致ID重复。

美团的Leaf解决了时钟回拨的问题,具体流程如下图,可以了解一下:


其他方式

当然,还有一些其他的ID生成方案,比如:

  • 滴滴:时间+起点编号+车牌号
  • 淘宝订单:时间戳+用户ID
  • 其他电商:时间戳+下单渠道+用户ID,有的会加上订单第一个商品的ID。
  • MongoDB的ID:也算是类snowflake的一种。通过“时间+机器码+pid+inc”共12个字节,4+3+2+3的方式最终标识成一个24长度的十六进制字符。


总结

如果不用于数据库主键,建议直接用UUID。

如果想要用来做数据库主键,又没有使用分布式数据库(比如TiDB、MongoDB等),可以考虑使用snowflake算法,建议使用美团的Leaf。

数据库中间件sharding-jdbc的分布式ID采用twitter开源的snowflake算法,不需要依赖任何第三方组件,这样其扩展性和维护性得到最大的简化;但是snowflake算法的缺陷(强依赖时间,如果时钟回拨,就会生成重复的ID),sharding-jdbc没有给出解决方案,如果用户想要强化,需要自行扩展。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
监控 安全 Java
应对Go语言在分布式系统中挑战的策略
【2月更文挑战第20天】Go语言在分布式系统中的应用日益广泛,但随之而来的挑战也不容忽视。本文将从内存管理、性能优化、安全性与可靠性等方面,探讨应对Go语言在分布式系统中挑战的策略,旨在为开发人员提供实用的解决方案和思路。
|
3天前
|
SQL 算法
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
10 1
|
6天前
|
算法
基于一致性理论的微电网分布式控制策略仿真模型【自适应虚拟阻抗】【simulink仿真】
基于一致性理论的微电网分布式控制策略仿真模型【自适应虚拟阻抗】【simulink仿真】
|
6天前
|
算法
【免费】基于ADMM算法的多微网电能交互分布式运行策略(matlab代码)
【免费】基于ADMM算法的多微网电能交互分布式运行策略(matlab代码)
|
6天前
|
算法 安全
基于价值认同的需求侧电能共享分布式交易策略(matlab完全复现)
基于价值认同的需求侧电能共享分布式交易策略(matlab完全复现)
|
8天前
|
算法 关系型数据库 MySQL
Go语言中的分布式ID生成器设计与实现
【5月更文挑战第6天】本文探讨了Go语言在分布式系统中生成全局唯一ID的策略,包括Twitter的Snowflake算法、UUID和MySQL自增ID。Snowflake算法通过时间戳、节点ID和序列号生成ID,Go实现中需处理时间回拨问题。UUID保证全局唯一,但长度较长。MySQL自增ID依赖数据库,可能造成性能瓶颈。选择策略时需考虑业务需求和并发、时间同步等挑战,以确保系统稳定可靠。
114 0
|
26天前
|
存储 SQL 算法
搞定了 6 种分布式ID,分库分表哪个适合做主键?
在《ShardingSphere5.x分库分表原理与实战》系列的第七篇文章中,作者探讨了分布式ID在分库分表中的重要性,以及如何利用`ShardingSphere-jdbc`的多种主键生成策略。文章介绍了`UUID`、`NanoID`、自定义雪花算法和`CosId`等策略的优缺点,并警告不要在SQL中手动拼接主键字段。此外,文章还展示了如何配置这些策略,并提醒读者`CosId`在5.2.0版本可能不可用。最后,文章讨论了如何自定义分布式主键生成算法,并强调选择策略时要考虑全局唯一性、性能和易用性。
111 1
|
2月前
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
111 2
深度思考:雪花算法snowflake分布式id生成原理详解
|
2月前
|
存储 缓存 监控
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据更新场景策略和方案分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据更新场景策略和方案分析)
15 0
|
2月前
|
NoSQL 算法 MongoDB
一文搞定分布式系统ID生成方案
一文搞定分布式系统ID生成方案
11 0