分布式id

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容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
相关文章
|
7月前
|
缓存 算法 NoSQL
【分布式详解】一致性算法、全局唯一ID、分布式锁、分布式事务、 分布式缓存、分布式任务、分布式会话
分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。副本一致性是针对分布式系统而言的,不是针对某一个副本而言。强一致性(strong consistency):任何时刻任何用户或节点都可以读到最近一次成功更新的副本数据。强一致性是程度最高的一致性要求,也是实践中最难以实现的一致性。单调一致性(monotonic consistency):任何时刻,任何用户一旦读到某个数据在某次更新后的值,这个用户不会再读到比这个值更旧的值。
662 0
|
4月前
|
算法 Go
[go 面试] 雪花算法与分布式ID生成
[go 面试] 雪花算法与分布式ID生成
|
1月前
|
算法 关系型数据库 MySQL
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
在分布式系统中,确保每个节点生成的 ID 唯一且高效至关重要。Snowflake 算法由 Twitter 开发,通过 64 位 long 型数字生成全局唯一 ID,包括 1 位标识位、41 位时间戳、10 位机器 ID 和 12 位序列号。该算法具备全局唯一性、递增性、高可用性和高性能,适用于高并发场景,如电商促销时的大量订单生成。本文介绍了使用 Go 语言的 `bwmarrin/snowflake` 和 `sony/sonyflake` 库实现 Snowflake 算法的方法。
39 1
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
|
17天前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
34 8
|
1月前
|
NoSQL 算法 关系型数据库
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
本文详解分布式全局唯一ID及其5种实现方案,关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
|
5月前
|
存储 NoSQL Java
通用快照方案问题之通过Sleuth进行耗时分析和链路优化如何解决
通用快照方案问题之通过Sleuth进行耗时分析和链路优化如何解决
49 0
|
5月前
|
消息中间件 Java Nacos
通用快照方案问题之通过Spring Cloud实现配置的自动更新如何解决
通用快照方案问题之通过Spring Cloud实现配置的自动更新如何解决
79 0
|
5月前
|
存储 算法 Java
分布式自增ID算法---雪花算法(SnowFlake)Java实现
分布式自增ID算法---雪花算法(SnowFlake)Java实现
301 0
|
6月前
|
存储 算法 Java
分布式唯一ID解决方案-雪花算法
分布式唯一ID解决方案-雪花算法
59 0
|
7月前
|
SQL 算法
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
110 1