图源:unsplash的唯一ID使开发者能够正确识别、保存和检索数据对象,并使数据对象参与到复杂的关系模式中。在整个应用程序开发周期中,程序员总是面临着生成唯一标识符的任务。这些唯一ID是如何生成的?哪种方法在不同的负载大小下效果最好?在多个计算节点竞争下一个可用ID的分布式环境中,ID如何保持唯一性?从小型单节点到推特级别,本文作者将介绍最常见的三种技术。通用唯一标识符-UUID通用唯一标识符(UUID)的概念大家都很熟悉,它已经在软件中使用多年。它是一个128位数字,当以受控和标准化的方式生成时,可以提供非常大的密钥空间,几乎消除了冲突的可能性。UUID是由几个不同部分组成的复合ID,例如时间、节点的MAC地址或MD5哈希的名称空间。为了适应所有这些组合,多年来,UUID规范已经演变为多个版本,主要是第1版和第4版。根据数据和业务领域的不同,一些开发人员可能对其他版本感兴趣。处理128位数字不是开发人员描述信息的最佳方式,因此UUID通常以规范文本表示,其中16个八位字节转换为32个十六进制字符,由连字符分隔,总共36个字符:UUID示例-版本4UUID最有趣的特性是它们可以单独生成,并且仍然保证在分布式环境中的唯一性。基本的ID生成算法并不复杂,不需要任何同步(至少低至100纳秒),并且可以并行执行:在分布式环境中生成唯一ID可以自生成唯一性的内在属性,使得UUID是分布式环境中最常用的ID生成技术之一。但是UUID需要额外的存储空间,这会对查询性能产生负面影响。持久性生成的ID如果您不想在应用程序级别生成唯一的ID,另一种常见的方法是使用持久性存储。所有最近的RDBMS都提供某种列数据类型,开发人员可以委派这些数据类型来生成唯一标识符。MongoDB提供了ObjectID,MySQL和MariaDB提供了AUTO_INCREMENT,MS-SQL-Server提供了IDENTITY等等。ID的实际表示会因实现而异,但唯一性的含义保持不变。持久层生成的ID缓解了必须在应用程序代码中生成唯一ID的问题。但是,如果您正在操作一个大型数据库集群,并且前面有非常繁忙的应用程序,这种方法可能就不够用了。还有另一个问题:生成的ID对于没有往返数据库的代码是未知的:RDBMSvsCodeGeneratedID在上图中,到RDBMS的额外往返可能会减慢应用程序,可能使代码变得不必要的复杂.然而,现代ORM框架有助于以标准化的方式做到这一点,而不管所使用的底层RDBMS产品如何。ID服务器或雪花IDID服务器负责为分布式基础设施生成唯一的ID。根据ID服务器执行的功能,它可以是创建ID的单个服务器,也可以是每秒创建大量ID的服务器集群。我不需要向您介绍Twitter。平均每秒产生9000条推文,峰值高达每秒143199条推文。Twitter需要一个解决方案来扩展其庞大的服务器基础设施并生成高效的存储ID。来源:unsplash这就是Twitter推出Snowflake计划的原因:Snowflake是一种可以大规模生成唯一ID号的网络服务,并且有一些基本的保证。Twitter之前使用的服务器每个进程每秒至少生成10,000个ID,并且响应时间小于2ms。ID服务器之间不需要网络协调,生成的ID应该大致按时间顺序排列,并且为了保持最小存储,生成的ID必须是紧凑的。为了解决上述项目,Twitter开发了Snowflake项目作为用Scala编写的Thrift服务器。生成的ID包括:时间-41位数字(毫秒精度)配置的机器ID-10位数字序列号-12位数字(每台机器每4096转)分布式ID生成器如何工作的基本原则仍然适用。因为每个生成器都是独立的,所以Twitter能够根据需要扩展其基础架构,而不会因集群同步和协调而产生额外的延迟。使用ID服务器的解决方案与代码生成ID的工作方式类似:ID服务器生成ID。您会发现性能仍然会因到ID服务器的往返而降低,但是由于不涉及复杂的数据库操作,因此这种额外的延迟小于ID服务器的延迟。将对象刷新到RDBMS的时间要短得多。ID服务器提供了一种中介解决方案,使开发人员能够控制唯一ID的生成方式和位置,而无需引入复杂的、会引起延迟的基础设施。生成唯一标识符是任何最终需要保存数据的应用程序的必要步骤。本文讨论三种常用方法:UUID-本地生成的ID、持久层驱动的ID-集中创建的ID和SnowflakeID-生成的ID作为Web服务。没有万能的解决方案。选择一种在您的应用程序中生成唯一ID的方法需要考虑数据、持久性选项和网络基础设施,以便选择适合您的需求和您的想法规模的方法。
