分布式系统生成全局唯一 ID 的方式请教

2023-07-25 14:53:59 +08:00
 jiobanma

咨询各位大佬们一个问题目前有两台服务器负载,使用 apache 的 SnowflakeShardingKeyGenerator 生成雪花算法作为 id ,业务上需要生成的 id 是递增的。 之前两台服务器的 SnowflakeShardingKeyGenerator 的 workId 都是默认的,高并发情况下,两台服务器的时间可能会有误差 就会导致生成的 id 是重复的。但是两台服务器根据不同的 workId 去生成虽然能解决重复的问题,但是会导致生成的 id 不是连续递增的。 有什么其他的方式实现吗(排过坑的[旺柴])。

9642 次点击
所在节点    Java
114 条回复
xrzxrzxrz
2023-07-25 20:29:38 +08:00
跟 23L 说的一样。把 workId 放在 ID 的尾部,时间日期放在前面,这样两个机器生成出来的 id 就是近似连续递增的(当然没法做到绝对递增,要绝对,只能有一个中间服务处理)。例如,{yyyyymmdd} + {workId} + {Hms}。(自己写个雪花算法原理的 id 生成器)
veike
2023-07-25 20:31:52 +08:00
@dayudayupao 能见降低多少啊
Macrow
2023-07-25 21:05:42 +08:00
https://github.com/rs/xid
零配置,可排序

Features:

Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake
Base32 hex encoded by default (20 chars when transported as printable string, still sortable)
Non configured, you don't need set a unique machine and/or data center id
K-ordered
Embedded time with 1 second precision
Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process
Lock-free (i.e.: unlike UUIDv1 and v2)

Name Binary Size String Size Features
UUID 16 bytes 36 chars configuration free, not sortable
shortuuid 16 bytes 22 chars configuration free, not sortable
Snowflake 8 bytes up to 20 chars needs machine/DC configuration, needs central server, sortable
MongoID 12 bytes 24 chars configuration free, sortable
xid 12 bytes 20 chars configuration free, sortable
iwdmb
2023-07-25 21:11:53 +08:00
如果没有中心化服务的话
没有这种可以严格递增的方法
不然 Google 就不用搞原子钟了
iwdmb
2023-07-25 21:17:16 +08:00
如果你能找到这样一个不依赖中心化服务、原子钟 GPS 硬体的方法
去面试 Google 一定会上
可以帮他们数据中心节省大量的成本
iwdmb
2023-07-25 21:18:06 +08:00
美团的 Leaf 只有保证整体趋势递增 不保证严格递增
UUID 有重复的可能 所以也不是严格递增
iwdmb
2023-07-25 21:24:32 +08:00
分布式严格递增
这个问题目前最简单、经济、性能最好的解法就是中心化服务
信我一把
mrjnamei
2023-07-25 21:56:54 +08:00
你服务是分布式的,要求每个服务生成的 id 必须是全局自增,因此必须引入一个新的组件来通信,不然无法得知当前服务器生成的 id 是否是递增的?

如果需要引入一个组件就比较好办了,高并发情况考虑高可用就行,高并发是指特别高的并发,假设服务 idGen 服务已经满足高可用的前提下,生成自增 id 显然不是问题,不管使用 redis 、还是自身内存都可以。

你要解决的问题就是高可用。
cosmic
2023-07-25 22:49:48 +08:00
用 etcd cluster 实现一个全局唯一且连续递增的 sequence generator,确保 consistency 和 availability. 然后服务器每次请求获取一个 batch 的 id,然后服务器每次 assign 一个,当一个 batch 用完后,向 sequence generator service 请求下一个 batch
tangtj
2023-07-25 22:53:04 +08:00
雪花算法是有预留,数据中心 id, 机器 id 的位置. 你没改那就需要调整配置.使他们不一样. 这样就不会出现完全一样的.
JohnChang
2023-07-25 23:09:43 +08:00
V 站到底多少人用这个头像啊?我怀疑是不是都抄我的
walkerliu
2023-07-25 23:21:23 +08:00
什么业务哇需要这么精确严格的递增吗,snowflakeID 前 41 个 bit 是 timestamp ,都能精确到毫秒了 。我觉得不如倒退需求是否需要那么精确的递增
conn457567
2023-07-25 23:23:04 +08:00
雪花算法的前提条件就是每个实例的 workerid 不能相同啊,可以用分布式协调中间件 zookeper 给每个实例分唯一 id ,或者简单点用 redis 来实现给每个实例分配唯一 id
L0L
2023-07-25 23:26:22 +08:00
高并发的场景下,雪花的递增不太可靠吧?最好说一下一定要递增的业务场景把,看看能不能换个角度解决这个问题?既然上了分布式 ID 了,尽量就避免用其作为业务含义上排序的用途吧,看看是否可以用时间戳之类的。否则 1 楼说的那个需要单独启动一个序列号服务,感觉如果只有两台服务器的话,代价反而有点高,不经济。
jdOY
2023-07-26 02:12:59 +08:00
就两台服务器搞这么复杂,服务器做一下时间同步,改一下生成雪花的几个参数就行了
ryd994
2023-07-26 04:00:28 +08:00
snowflak 本来就不保证是完全单调递增,而是保证 ID 大体上是单调连续递增,但是允许小规模,短时间的无序
xuanbg
2023-07-26 06:25:39 +08:00
分布式系统你是很难保证严格按照时间同步递增的,保证单机单调递增就够了。
franklu
2023-07-26 08:06:21 +08:00
我想问一下,在分布式下,你们怎么测试确保 id 是不重复的,要是有成熟测试方案,我觉得写代码会更简单。
franklu
2023-07-26 08:07:05 +08:00
还是说只能用思维模型测试,只能理论上推理出没问题。
trzzzz
2023-07-26 08:34:09 +08:00
为啥不用数据库的自增 id 呢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://yangjunhui.monster/t/959560

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX