分布式id

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 当产品使用人数达到一定量级,一般会采用分库分表等优化操作,但是分布式 id 如何保证全局唯一呢?

UUID 全称是 Universally Unique Identifier ,翻译为通用唯一识别码。此码由网卡 MAC 地址、时间戳、时序、随机数等等一系列元素组合而成,从而保证唯一。碰撞几率几乎为零,大可不必考虑重复问题,放心使用即可。其被广泛应用于各种场景,如图片验证码编号,分布式 id 等。

UUID 是由128位二进制组成,一般转换为十六进制,然后使用 String 表示。

1.1 优点

1) 通过本地生成,没有经过网络 I/O,性能较优

2) 无序,无法预测其生成顺序

但是无序也变成了它的缺点之一

1.2 缺点

1) 128位二进制一般转换成36位的十六进制,因为过于长只能使用 String 存储,空间占用较多

2) 不能生成递增有序的数字。这就导致作为数据库表主键之后效率远不及自增主键

由于不规则,每向数据库插入一条数据就需要重新排列,因此效率不及自增主键

2.数据库表自身主键

在使用唯一标识符时,下意识会考虑到主键自增,因为经常使用,似乎并没有什么问题。但是不要忘记,一般公司产品并未达到分库分表的使用场景,所以不会有任何问题,但并不代表其一直有效。那么它就无法使用了吗?当然不是,可以使用特殊方式:

1) 单独维护一张表,用来生成 id 供分库分表之后共同使用,保证唯一。但是由于所有数据库依赖这张表,其一旦发生意外将导致服务直接崩掉无法使用,所以需要三思而后行。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』

2) 使用主键的另外一种方式,设置起始值与步长。比如分了两张表,第一张表的主键从1开始,步长为2,表现为:1,3,5 ... 第二张表的主键从2开始,步长为2,表现为:2,4,6 ...

2.1 优点

1) 简单方便

2) 有序递增

3) 方便排序和分页

2.2 缺点

1) 分库分表会带来问题,需要进行特殊处理

2) 并发性能不高,受限于数据库的性能

3) 简单递增容易被其他人猜测利用。比如你有一个用户服务的递增,那么其他人可以根据分析注册的用户 id 来得到当天你的服务有多少人注册,从而描绘出此服务当前整体状况。

4) 数据库宕机后服务不可用

3.Redis

不要认为 redis 只可以用来做缓存,它的使用场景超多。此处利用命令 incr 即可生成分布式 id

incr 命令是将 key 中存储的数字值进行加一操作。如果 key 不存在,那么其值会被初始化为0.

注意:因为 Redis 是单线程的,所以可以保证原子性。就不要再担忧并发数据出错问题了 ~更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』

3.1 优点

1) 性能比数据库高得多

2) 能满足有序递增的要求

3.2 缺点

1) redis 是基于内存的键值数据库,虽然有 AOFRDB 等持久化操作,但是依然会存在数据丢失问题,从而导致 id 不唯一。

有人会问,数据丢失和不唯一有什么关联?比如数据库生成的主键到111113了,但是发生宕机,有一秒的数据丢失,恢复后从111111开始计算,因此重复了两个值111112和111113。

2) 依赖于 redis ,如果其不稳定,那么也会影响 id 的生成。

4.雪花算法

雪花算法由 Twitter 提出,英文名为 Snowflake ,它的目的是生成一个 64bit 的整数(1bit符号位 + 41bit时间戳 + 10bit工作机器id + 12bit序列号 )。由于其保持增长有序并能通过处理保证唯一而被各大厂商广泛应用于分布式,比如头条。

1) 1bit 是符号位,不做任何处理

2) 41bit 用来记录时间戳,这里可以记录69年,如果设置好起始时间,比如今年是2020年,那么可以用到2089年。有人会问,到时候怎么办?放心吧,一般产品的生命周期不到69年,即使它活过了69年,此系统一定重构过好多次,因此不是问题

3) 10bit 用来记录机器的 id ,总共可以记录1024台。一般前5位代表数据中心,后面5位是某个数据中心的机器 id

4) 12bit 是循环位,用来解决同一个毫秒之内产生不同的 id 。12位最多可以记录4095个,也就是在同一个机器同一毫秒最多记录4095个,多余的需要进行等待下一毫秒

上述规范适用于 64bit 划分标准,其他情况可以根据实际场景划分。比如:服务目前 QPS 10万,预计几年之内会发展到百万;当前机器三地部署(上海、北京和贵州);机器共有10台左右,预计未来增加到百台以上。

这个时候我们根据上面的场景可以再次合理划分 62bitQPS 几年之内到百万,那么每毫秒就是千级请求,目前10台机器每台承担百万级的请求,为了保证扩展,后面的循环位可以限制到1024,也就是2的10次方,循环位10位足矣。机器三地部署,我们可以用 3bit 总共8来表示机房位置,当前的机器10台,为了保证扩展到百台,可以使用 7bit 也就是128来表示,时间位依然是 41bit ,那么还剩下 64-10-3-7-41-1,也就是 2bit。剩下的 2bit 可以用来进行扩展。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』

QPS 是每秒查询率

4.1 优点

1) 由于时间戳是不断增大的,再加上循环位不断增加,其他位置相对固定,所以可以保证生成有序的 id,提高数据库的性能。

4.2 缺点

1) 时间回拨问题可能导致重复 id

雪花算法强依赖时间,而我们的机器可能因为各种原因发生时间回拨(与时间服务器校准,发现机器时间快了,往回调一下),这就导致有可能生成重复 id

解决方案一:用当前时间和上一次时间进行判断,如果发生回拨,算法抛出错误,保证不重复(用户看到提示界面,再次进行操作时,肯定已经过了几秒,所以我们毫秒级的处理丝毫不慌,用户体验也并不会降低)。

解决方案二:关闭机器与 ntp 同步

总结

四种方案各有优缺点,可以根据产品体量自行选择。不过推荐雪花算法。你懂得

相关实践学习
基于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
相关文章
|
4月前
|
缓存 算法 NoSQL
【分布式详解】一致性算法、全局唯一ID、分布式锁、分布式事务、 分布式缓存、分布式任务、分布式会话
分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。副本一致性是针对分布式系统而言的,不是针对某一个副本而言。强一致性(strong consistency):任何时刻任何用户或节点都可以读到最近一次成功更新的副本数据。强一致性是程度最高的一致性要求,也是实践中最难以实现的一致性。单调一致性(monotonic consistency):任何时刻,任何用户一旦读到某个数据在某次更新后的值,这个用户不会再读到比这个值更旧的值。
423 0
|
3天前
|
SQL 算法
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
10 1
|
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月前
|
NoSQL 算法 MongoDB
一文搞定分布式系统ID生成方案
一文搞定分布式系统ID生成方案
11 0
|
2月前
|
算法 NoSQL Java
Java实战:分布式ID生成方案
在分布式系统的设计与开发过程中,如何生成全局唯一、有序且高可用的ID是一个绕不开的核心问题。尤其是在电商、社交网络、金融交易等领域,ID不仅是业务数据的重要标识,还可能直接影响系统的稳定性和扩展性。本文将深入剖析分布式ID生成方案的设计原则、常见算法,并通过Java示例展示一种可行的实现方式。
46 2
|
2月前
|
算法 Java 数据中心
分布式ID生成系统之雪花算法详解
在当今的云计算和微服务架构盛行的时代,分布式系统已成为软件开发的重要组成部分。随着系统规模的扩大和业务的复杂化,对数据一致性和唯一性的要求也越来越高,尤其是在全局唯一标识符(ID)的生成上。因此,分布式ID生成系统应运而生,成为保证数据唯一性和提高系统可扩展性的关键技术之一。雪花算法(Snowflake)是Twitter开源的一种算法,用于生成64位的全局唯一ID,非常适用于分布式系统中生成唯一标识符。下面我们将深入探讨雪花算法的原理、结构和实现方式。
117 2
 分布式ID生成系统之雪花算法详解
|
2月前
|
NoSQL 算法 Java
【Redis】4、全局唯一 ID生成、单机(非分布式)情况下的秒杀和一人一单
【Redis】4、全局唯一 ID生成、单机(非分布式)情况下的秒杀和一人一单
67 0
|
3月前
|
存储 算法 NoSQL
全网最全的分布式ID生成方案解析
全网最全的分布式ID生成方案解析
153 0