0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分布式系统的主键生成方案对比

OSC开源社区 来源:OSCHINA 社区 2023-09-20 10:36 次阅读

来源| OSCHINA 社区

作者 |京东云开发者-京东物流 金越

UUID

UUID(通用唯一识别码)是由 32 个十六进制数组成的无序字符串,通过一定的算法计算出来。为了保证其唯一性,UUID 规范定义了包括网卡 MAC 地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素,以及从这些元素生成 UUID 的算法。一般来说,算法可以保证任何地方产生的任意一个 UUID 都不会相同,但这个唯一性是有限的,只在特定的范围内才能得到保证。 UUID 的一个非常明显的特点就是本身较长,格式是这样的:

xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx
467e8542-2275-4163-95d6-7adc205580a9
其中 M 位置,代表版本号,由于 UUID 的标准实现有 5 个版本,所以只会是 1、2、3、4、5;

各版本介绍

UUID 现有的 5 种版本,是根据不同的使用场景划分的,而不是根据精度,所以 Version5 并不会比 Version1 精度高,在精度上大家都能保证唯一性,重复的概率近乎于 0。 总结:

使用 UUID,每个人都可以创建不与其它人冲突的唯一值,在所有空间和时间上都可以被视为唯一的标识。

UUID 可单机自行生成,且生成速度快,QPS 高,各个语言都有对应的生成供直接调用使用。

如果只是需要生成一个唯一 ID,可以使用 V1 或 V4。v1 基于时间戳和 Mac 地址,这些 ID 有一定的规律,而且会暴露你的 Mac 地址。v4 是完全随机 (伪) 的。

如果对于相同的参数需要输出相同的 UUID, 你可以使用 V3 或 V5。

Version1: 基于时间戳及 MAC 地址的实现

其中包括了 48 位的 MAC 地址和 60 位的时间戳。且 v1 为了保证唯一性,当时间精度不够时,会使用 13~14 位的 clock sequence 来扩展时间戳,比如:当 UUID 的生产成速率太快,超过了系统时间的精度。时间戳的低位部分会每增加一个 UUID 就 + 1 的操作来模拟高精度的时间戳,换句话说,就是当系统时间精度无会区分 2 个 UUID 的时间先后时,为了保证唯一性,会在其中一个 UUID 上 + 1。所以 UUID 重复的概率几乎为 0,时间戳加扩展的 clock sequence 一共有 74bits,(2 的 74 次方,约为 1.8 后面加 22 个零), 即在每个节点下,每秒可产生 1630 亿不重复的 UUID。 但由于 v1 中最后的 12 位是网卡的 MAC 地址,会导致隐私问题以及安全问题,这是这个版本 UUID 受到批评的地方。

Version2: DCE 安全的 UUID

DCE(Distributed Computing Environment)安全的 UUID 和基于时间的 UUID 算法相同,但会把时间戳的前 4 位置换为 POSIX 的 UID 或 GID。这个版本的 UUID 在实际中较少用到。

Version3: 5 基于名称空间和名字

v3 和 v5 都是通过计算 namespace 和名称的哈希值生成的。不同的点在于 v3 使用的 hash 算法为 MD5,v5 使用 SHA-1。因为算法中没有不确定的部分,所以当 namespace 与名称确定时,得到的 UUID 都是确定唯一的。比如:

$ uuid -n 3 -v3 ns:URL www.jd.com
7e963853-8fce-3085-bb2c-8424745d73a2
7e963853-8fce-3085-bb2c-8424745d73a2
7e963853-8fce-3085-bb2c-8424745d73a2
算法实现中会将 namespace 和输入参数拼接在一起,计算 hash 结果,再进行截断格式化等操作来保证唯一性。

Version4: 基于随机数

v4 的 UUID 中 4 位代表版本,2-3 位代表 variant。余下的 122-121 位都是全部随机的。即有 2 的 122 次方 (5.3 后面 36 个 0) 个 UUID。一个标准实现的 UUID 库在生成了 2.71 万亿个 UUID 会产生重复 UUID 的可能性也只有 50% 的概率。这相当于每秒产生 10 亿的 UUID,持续 85 年,而把这些 UUID 都存入文件,每个 UUID 占 16bytes, 总需要 45EB (exabytes),比目前最大的数据库 (PB) 还要大很多倍。 在 java 中使用 v4:

# java 1.5+ 
# java.util.UUID

for (int i = 0; i < 3; i++) {
String uuid = UUID.randomUUID().toString();
System.out.println(uuid);
}

生成的 UUID 如下:

8bca474b-214d-4ce8-8446-b99f30147f94
c38588cf-a1c4-4758-9d86-b2ee5552ae59
febf5a46-bd1b-43f8-89a8-d5606e5d1ce0
由于这个版本使用非常简单,因此使用最为广泛。

SnowFlake 算法

雪花算法,是 Twitter 开源的分布式 ID 生成算法。雪花算法中利用了时间戳,机器 ID,以及同毫秒内的不同序列号来保证分布式生成 ID 的唯一性。 雪花算法总结 1. 时间戳在高位,自增序列在低位的特征可以保证整个 ID 的趋势是递增有序的。 2. 但由于其依赖机器时钟,如果机器时钟回拨,可能会导致重复 ID 生成。其在分布式环境下,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况。 SnowFlake 算法生成 id 的结果是一个 64bit 大小的整数,它的结构如下图: f13ace08-56de-11ee-939d-92fbcf53809c.png

1bit,不用。二进制中最高位为 1 的都是负数,但是我们生成的 id 一般都使用整数,所以这个最高位固定是 0

41bit,用来记录时间戳(毫秒)。41 位可以表示 2^{41}-1 个数字,如果只用来表示正整数(计算机中正数包含 0),可以表示的数值范围是 0 至 2^{41}-1,也就是说 41 位可以表示 2^{41}-1 个毫秒的值,转化成单位年则是 (2^{41} - 1) / (1000*60*60*24*365) = 69 年。

10bit,用来记录工作机器 id。可以部署在 2^{10} = 1024 个节点,包括 5 位 datacenterId 和 5 位 workerId,5 位(bit)可以表示的最大正整数是 2^{5}-1 = 31,即可以用 0、1、2、3、....、31 这 32 个数字,来表示不同的 datecenterId 或 workerId。

12 位,序列号,用来记录同毫秒内产生的不同 ID;12bit 可以表示的最大正整数是 2^{12}-1 = 4095 ,即可以用 0、1、2、3、....4094 这 4095 个数字,来表示同一机器同一时间截(毫秒) 内产生的 4095 个 ID 序号。

有序主键 or 随机主键 ?

使用 UUID 这些随机 ID 生成算法作为 MySQL 主键的生成方案呢?答案是:不可以! 众所周知,当 MySQL 数据表使用 InnoDB 作为存储引擎时,每一个索引都对应一个 B + 树,若表定义了主键(没有时,MySQL 则会自动生成不可见的自增主键),主键对应的索引就是聚簇索引,表的所有数据都存储在聚簇索引上。索引中键值的逻辑顺序决定了表中相应行的物理顺序(索引中的数据物理存放地址和索引的顺序是一致的)。可以这么理解:只要是索引是连续的,那么数据在存储介质上的存储位置也是连续的。 基于以上特性,由于自增键的值是有序的,插入数据时,Innodb 会把每一条记录都存储在上一条记录的后面。当达到页面的最大填充因子时候 (innodb 默认的最大填充因子是页大小的 15/16, 会留出 1/16 的空间留作以后的修改),会进行如下操作:下一条记录就会写入新的页中,一旦数据按照这种顺序的方式加载,主键页就会近乎于顺序的记录填满,提升了页面的最大填充率,不会有页的浪费;且由于新插入的行一定会在原有的最大数据行下一行,mysql 定位和寻址很快,不会为计算新行的位置而做出额外的消耗。 而 UUID 相对于有序的自增 ID,它的值是毫无规律可言的,新行的主键不一定要比之前数据主键的值大,所以 innodb 无法做到总是把新行插入到索引的最后,而是需要为新行寻找新的合适的位置从而来分配新的空间。这个过程需要做很多额外的操作,而且最终分布散乱的数据会导致以下问题:

写入的目标页很可能已经刷新到磁盘上并且从缓存上移除,或者还没有被加载到缓存中,innodb 在插入之前不得不先找到并从磁盘读取目标页到内存中,这将导致大量的随机 IO;

因为写入是乱序的,innodb 不得不频繁的做页分裂操作,以便为新的行分配空间,页分裂导致移动大量的数据,一次插入最少需要修改三个页以上,且由于频页分裂,页会变得稀疏并被不规则的填充,最终会导致数据会有碎片;

在把值载入到聚簇索引 (innodb 默认的索引类型) 以后,有时候会需要做一次 OPTIMEIZE TABLE 来重建表并优化页的填充,这将又需要一定的时间消耗。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4459

    浏览量

    90768
  • Mac
    Mac
    +关注

    关注

    0

    文章

    1067

    浏览量

    50852
  • 分布式系统
    +关注

    关注

    0

    文章

    140

    浏览量

    19099
  • UUID
    +关注

    关注

    0

    文章

    22

    浏览量

    8029

原文标题:分布式系统的主键生成方案对比

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    分布式软件系统

    。更重要的是,NI LabVIEW 8的分布式智能提供的解决方案不仅令这些挑战迎刃而解,且易于实施。LabVIEW 8的分布式智能具体包括: 可对分布式
    发表于 07-22 14:53

    使用分布式I/O进行实时部署系统的设计

    的8插槽机箱,与LabVIEW Real-Time的强大功能相结合,为确定性分布式I/O提供了便捷的解决方案。介绍当你需要在实时控制系统中设计分布式I/O时,你将怎么办?首要问题就是如
    发表于 03-12 17:47

    分布式文件系统和fastDFS

    项目(1)(分布式文件系统、fastDFS,代码实现fastDFS 文件上传和下载)
    发表于 05-10 08:51

    关于分布式系统的全面介绍

    操作系统-----分布式系统概述
    发表于 07-25 06:59

    如何设计分布式干扰系统

    什么是分布式干扰系统分布式干扰系统是一种综合化、一体化、小型化、网络化和智能化系统,是将众多体积小,重量轻,廉价的小功率侦察干扰机装置在易
    发表于 08-08 06:57

    分布式系统的优势是什么?

    当讨论分布式系统时,我们面临许多以下这些形容词所描述的 同类型: 分布式的、删络的、并行的、并发的和分散的。分布式处理是一个相对较新的领域,所以还没有‘致的定义。与顺序计算相比、并行的
    发表于 03-31 09:01

    Qorvo分布式Wi-Fi网格解决方案

    实现互联世界的创新RF解决方案提供商Qorvo宣布,正使用 802.11ax 产品组合扩大分布式 Wi-Fi 解决方案在住宅中的适用范围。该产品组合可改善 Wi-Fi 覆盖范围,帮助实现更小的器件
    发表于 11-02 07:01

    分布式KVM坐席拼控系统解决方案

    ,形成一个信息共享的云管理平台。 视通科技经过多年来对技术的深入研究和对用户使用习惯的积累,推出了AS-ADS 4K分布式KVM坐席拼控解决方案,本系统是一套技术先进、功能完善、性能稳定、安全可靠、操作
    发表于 02-26 15:15

    求一种独特的DCS分布式系统的测试方案

    本文介绍一种独特的DCS分布式系统的测试方案,对分布在一个网络中多台电脑上的各个系统模块(每台电脑运行多个
    发表于 04-26 06:57

    如何对分布式天线系统(DAS)进行优化?

    什么是分布式天线系统?如何对分布式天线系统(DAS)进行优化?
    发表于 05-24 06:03

    分布式系统时钟解决方案

    )Naive HLC改进HLC本文将首先依次简单介绍分布式系统下的物理时钟(Physical Time,也称PT),逻辑时钟(Logical Clock,也称LC),向量时钟(Vector Clock,也称VC
    发表于 06-28 10:46

    萌新求助,求一个分布式光伏发电监测系统解决方案

    萌新求助,求一个分布式光伏发电监测系统解决方案
    发表于 10-22 07:59

    如何高效完成HarmonyOS分布式应用测试?

    作者:liuxun,HarmonyOS测试架构师HarmonyOS是新一代的智能终端操作系统,给开发者提供了设备发现、设备连接、跨设备调用等丰富的分布式API。随着越来越多的开发者投入到
    发表于 12-13 18:07

    【学习打卡】OpenHarmony的分布式任务调度

    、同步、注册、调用)机制。分布式任务调度程序是能够跨多个服务器启动调度作业或工作负载的软件解决方案,整个过程是不需要人来值守的。举个例子,我们可以在一台或多台机器上安装分布式调度器,用户可以通过它在
    发表于 07-18 17:06

    为什么需要分布式ID?求一种分布式ID生成方案

    对于单体系统来说,主键ID可能会常用主键自动的方式进行设置,这种ID生成方法在单体项目是可行的,但是对于分布式
    的头像 发表于 01-09 10:43 796次阅读