当前位置: 首页 > 科技观察

浅谈几种常见的分布式ID_0

时间:2023-03-20 18:24:56 科技观察

1。UUIDUUID可以在时间和空间上产生唯一的值,其本质是随机性和规则的结合。即使UUID是在两个独立的服务器上生成的,其预期值也是不同的。以MySQL为例来说明UUID。格式在MySQL中,UUID值是一个128位数字,表示为以下格式的十六进制数字的utf8字符串:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeeeeee。得到的随机值由5部分组成,分隔位为:破折号。各部分含义如下:前三组值由时间戳转换而来;第四组值是暂时保持时间戳的唯一性。例如,使用夏令时;第五组值是空间唯一的IEE802节点标识值。如果后者不可用,则用一个随机数代替。如果宿主机没有网卡,或者我们不知道如何获取某个系统下的机器地址,空间的唯一性就无法保证,即使出现重复值的几率很小。在MySQL环境下,多次调用或执行得到的最后两组值是相同的。如果把mysqld服务器关闭再重启,你会发现第四组从重启前的值开始变了,然后又没有变。只要重启启动mysqld服务就会改变。还有,对于同一台机器,第五组值永远不变。优点使用UUID作为主键有以下优点:UUID值在表、数据库甚至服务器之间是唯一的,允许您合并来自不同数据库的行或跨服务器分布数据库。UUID值不会泄露有关数据的信息,因此在URL中使用更安全。UUID值可以在避免往返数据库服务器的任何地方生成。它还简化了应用程序中的逻辑。缺点除了优点之外,UUID值也有一些缺点:存储UUID值(16字节)比整数(4字节)甚至大整数(8字节)占用更多的存储空间。调试好像比较难,试想一下WHEREid='9d6212cf-72fc-11e7-bdf0-f0def1e6646c'和WHEREid=10哪个更舒服?使用UUID值可能会导致性能问题,因为它们的大小和未排序。数据库案例:MySQL在MySQL中内置了对UUID的支持。使用中有几个问题需要注意。作为主键问题,UUID()函数生成的值不适合作为InnoDB引擎表的主键。因为格式是无序的,存储为索引组织表会带来很大的管理开销。格式问题在MySQL中,可以使用UUID()来生成主键,但是使用MySQL的UUID()函数,生成的UUID是36位的,其中包含32个字符和4个分隔符(-),往往这个分隔符对us,可以使用MySQL自带的REPLACE函数去掉分隔符。内置函数支持在MySQL中,UUID值可以通过以下函数以紧凑格式(BINARY)存储并以人类可读格式(VARCHAR)显示:UUID_TO_BIN、BIN_TO_UUID、IS_UUID。请注意,UUID_TO_BIN()、BIN_TO_UUID()和IS_UUID()函数仅在MySQL8.0或更高版本中可用。-UUID_TO_BIN()函数将UUID从人类可读格式(VARCHAR)转换为紧凑格式(BINARY)格式进行存储-BIN_TO_UUID()函数将UUID从紧凑格式(BINARY)转换为人类可读格式(VARCHAR)-IS_UUID()函数可以用于确定参数是否为字符串格式的有效UUID。2.NanoIDUUID是软件开发中最常用的通用标识符之一。然而,在过去几年中,其他竞争对手对其存在提出了挑战。其中,NanoID是UUID的主要竞争对手之一。但是,这两者之间的主要区别很简单。它归结为用于键的字母表。由于NanoID使用比UUID更大的字母表,因此较短的ID可以用于与较长的UUID相同的目的。优点是更小NanoID只有108字节那么大。与UUID不同,NanoID的大小要小4.5倍,并且没有任何依赖性。此外,大小限制已用于将大小再减少35%。大小缩减直接影响数据的大小。例如,使用NanoID的对象小巧紧凑,可用于数据传输和存储。这些数字随着应用程序的增长而变得明显。更安全在大多数随机生成器中,它们使用不安全的Math.random()。但是,NanoID使用加密模块和WebCryptoAPI,这意味着NanoID更安全。此外,NanoID在ID生成器的实现中使用了自己的算法,称为统一算法,而不是使用“随机%字母表”随机%字母表。FasterNanoID既快速又紧凑,NanoID比UUID快60%。与UUID字母表中的36个字符不同,NanoID只有21个字符。更多语言NanoID支持14种不同的编程语言,它们是:C#、C++、Clojure和ClojureScript、Crystal、Dart&Flutter、Deno、Go、Elixir、Haskell、Janet、Java、Nim、Perl、PHP、带字典的Python、红宝石、铁锈、斯威夫特。更好的兼容性它还支持PouchDB、CouchDBWebWorkers、Rollup和React以及Reach-Native等库。我们可以使用npxnanoid来获取终端中的唯一ID。在JavaScript中使用NanoID的唯一要求是首先安装NodeJS。自定义字母表NanoID的另一个现有功能是它允许开发人员使用自定义字母表。我们可以更改文本或id的大小。在下面的示例中,我将自定义字母表定义为ABCDEF1234567890并将Id的大小定义为12。constnanoid=customAlphabet('ABCDEF1234567890',12);model.id=nanoid();无第三方依赖由于NanoID不依赖于任何第三方依赖,随着时间的推移它将能够变得更加稳定和自主。从长远来看,这有助于优化包的大小,并使其不易出现依赖性问题。数据库案例——ShardingSphere原生的数据库产品大多不支持NanoID,但可以通过外部方式引用。例如在开源项目ApacheShardingSphere中,通过规则的配置,NanoID可以作为其分片表的主键生成器。参考如下配置:CREATESHARDINGTABLERULEt_order(RESOURCES(ds_3307,ds_3308),SHARDING_COLUMN=order_id,TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME=NanoID,PROPERTIES("worker-id"=123)));CREATETABLEt_order(user_idintNOTNULL,statusvarchar(50)DEFAULTNULL,PRIMARYKEY(order_id))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;3。SnowFlake分发UUID(UniversallyUniqueIdentifier,全球唯一标识码)在传统系统的ID生成方案中比较简单,但有两个明显的缺点:1.UUID长128位,长度过长;2.UUID是完全随机的,不可能生成递增排序的UUID。现在流行的基于Snowflake雪花算法的ID生成方案可以很好的解决UUID的这两个问题。原理Snowflake雪花算法,由Twitter提出,开源,可以在分布式环境下生成唯一ID的算法。该算法生成一个64位ID。在同一个进程中,它首先通过时间位来保证不重复,如果时间相同,则通过顺序位来保证。同时,由于时间位是单调递增的,如果各个服务器的时间大致同步,那么生成的主键在分布式环境下一般可以认为是有序的,保证了插入索引字段的效率。比如MySQL的Innodb存储引擎的主键。该格式使用雪花算法生成的主键。二进制表示由4部分组成,从高到低依次为:1位符号位、41位时间戳位、10位工作过程位和12位序号位。符号位(1bit)保留的符号位始终为零。时间戳位(41bit)41位的时间戳可以容纳的毫秒数是2的41次方,一年使用的毫秒数是:365*24*60*60*1000。通过计算可知:Math.pow(2,41)/(365*24*60*60*1000L);结果大约等于69.73年。ApacheShardingSphere的雪花算法的时间纪元从2016年11月1日午夜开始,可以使用到2086年,相信可以满足大部分系统的要求。Workerprocessbit(10bit)这个标志在Java进程中是唯一的。如果是分布式应用部署,应该保证每个worker进程的id是不同的。该值默认为0,可以通过属性设置。序列号位(12bit)该序列用于在同一毫秒内生成不同的ID。如果这个毫秒内产生的数量超过4096(2的12次方),生成器会等到下一毫秒继续生成。优点使用SnowFlake的优点是占用空间小,有一定的顺序,对MySQL这样的数据库比较友好。缺点由于其生成策略需要参考当前时间,服务器时钟回拨时会造成重复序列。因此,默认的分布式主键生成器提供了时钟回调毫秒的最大容忍度。如果时钟回调时间超过最大容忍毫秒阈值,程序会报错;如果在可容忍的范围内,默认的分布式主键生成器会等待时钟同步到上次生成主键的时间再继续工作。以毫秒为单位的最大容忍时钟返回默认值为0,可以通过属性设置。数据库案例——ShardingSphere原生数据库产品大多不支持SnowFlake,但可以通过外部方式引用。例如在开源项目ApacheShardingSphere中,通过配置规则,可以将SnowFlake作为其分片表中的主键生成器。参考如下配置CREATESHARDINGTABLERULEt_order(RESOURCES(ds_3307,ds_3308),SHARDING_COLUMN=order_id,TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME=Snowflake,PROPERTIES("worker-id"=123)));CREATETABLEt_order(order_idvarchar(50)NOTNULL,user_idintNOTNULL,statusvarchar(50)DEFAULTNULL,PRIMARYKEY(order_id))引擎=InnoDBDEFAULTCHARSET=utf8mb4;作者介绍韩峰,51CTO社区编辑,CCIA(中国计算机协会)常务理事,前Oracle?ACE,腾讯TVP,阿里云MVP,dbaplus等社区创始人或专家组成员。具有丰富的一线数据库架构、软件开发、产品设计、团队管理经验。曾担任多家公司的首席DBA和数据库架构师。涉足云、电子商务、金融、互联网等行业,精通各种关系型数据库,也涉足NoSQL和大数据相关技术,具有丰富的实战经验。他撰写了与数据库相关的书籍《SQL优化最佳实践》和《数据库高效优化》。

最新推荐
猜你喜欢