☆* o(≧▽≦)o *☆嗨~我是小奥
个人博客:小奥的博客
CSDN:个人CSDN
Github:传送门
面经分享(牛客主页):传送门
文章作者技术和水平有限,如果文中出现错误,希望大家多多指正!
如果觉得内容还不错,欢迎点赞收藏关注哟! ❤️
文章目录
- 全局唯一ID(分布式ID)
-
- 1、UUID
- 2、数据库自增ID
- 3、数据库集群模式ID
- 4、Redis自增ID
- 5、雪花算法(SnowFlake)
全局唯一ID(分布式ID)
1、UUID
不推荐使用。因为UUID是随机字符串,如果作为订单号看不出和订单有任何相关的信息;而对于数据库来说用作业务主键ID,它是字符串而且太长,存储性能差和查询也很耗时,所以不推荐使用。
优点:生成简单,具有唯一性。
缺点:
- 无序字符串,不具备自增特性;
- 作为数据库业务主键的话查询性能非常差
2、数据库自增ID
最常见的一种生成id方式。利用数据库本身来进行设置,在全数据库内保持唯一。
优点:
- 实现简单,利用数据库现有功能实现
- ID号自增的,对于排序或者分页这种需求有性能的提升。
缺点:
- 强依赖数据库,不支持数据迁移,不同数据库的语法和实现不同,数据迁移的时候需要特殊处理。
- 可预测性,自增ID是连续的整数序列,可以被预测和猜测
- 在分布式架构多MySQL实例情况下,可能会导致ID重复
3、数据库集群模式ID
针对于单节点数据库自增ID存在的问题,我们可以对集群数据库的每一台节点的ID生成设置一个初始值和步长。
优点:
- 全局唯一:数据库集群模式ID可以保证在分布式系统中的全局唯一性,可以用于唯一标识实体。
- 支持自定义规则:可以根据需求自定义生成ID的规则和算法,例如可以使用时间戳和机器ID组合生成有序ID。
缺点:不易扩展:在使用一些分布式数据库的时候,扩展数据节点数量可能是非常困难的。
4、Redis自增ID
Redis的incr命令具备了incr and get的原子操作;Redis是单进程单线程架构,不会出现ID重复的问题。
优点:
- 简单易用:Redis自增ID是在Redis中使用INCR命令可以自动生成的,不需要额外的生成算法或过程。
- 高性能:Redis自增ID是内存中自增的,读写速度非常快,可以满足高并发场景下的需求。
- 全局唯一:Redis可以作为分布式系统中的中心缓存,使用自增ID可以保证在分布式系统中的全局唯一性。
缺点:
- 不易扩展:Redis是单线程的,不能充分利用多核CPU,扩展节点数量可能是非常困难的。
- 不支持跨Redis集群的唯一性:在使用多个Redis集群时,需要额外的工作来保证ID的全局唯一性。
需要考虑Redis持久化的问题。
- RDB:RDB定时将数据存入快照,如果连续自增的数据还没有来得及持久化,Redis出现了宕机,重启后Redis也会出现ID重复的问题。
- AOF:AOF会对每条命令都进行持久化,即时Redis宕机也不会出现ID重复,但是incr命令的特殊性,会导致Redis重启恢复数据时间较长。
5、雪花算法(SnowFlake)
Snowflake
生成的是Long类型的ID,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特。
Snowflake ID组成结构:正数位
(占1比特)+ 时间戳
(占41比特)+ 机器ID
(占5比特)+ 数据中心
(占5比特)+ 自增值
(占12比特),总共64比特组成的一个Long类型。
- 第一个bit位(1bit):符号位,一般默认为0
- 时间戳部分(41bit):毫秒级的时间,不是存储的当前时间戳,而是(当前时间 - 固定开始时间戳),可以使产生的ID从更小的值开始,41位的时间戳可以使用69年。(
(1L << 41)/(1000L * 60 * 60 * 24 * 365) = 69
)
- 工作机器ID(10bit):也被叫做workId,这个可以灵活配置,机房或者机器号组合都可以
- 序列号部分(12bit):自增值支持同一毫秒内可以生成4096个ID
优点:
- 简单易用:雪花算法的实现相对简单,易于集成到各种系统中。
- 高性能:雪花算法生成ID的速度非常快,可以满足高并发场景下的需求。
- 全局唯一:雪花算法生成的ID是全局唯一的,可以用于唯一标识实体。
- 支持排序:雪花算法生成的ID是有序的,可以按照ID排序和查询。
缺点:
- 依赖时钟回拨:雪花算法中的时间戳需要保证唯一性,如果发生时钟回拨,可能会导致生成重复的ID。
- 时钟同步性要求高:为了避免时钟回拨的问题,雪花算法要求系统中的所有节点的时钟必须保持同步。