Hollis的新书限时折扣中,一本深入讲解Java基础的干货笔记!

在《悟空传》篇外篇里,有一个忧伤的故事。

秋天,树上掉下两片叶子,你要和它们说再见。但你如何知道这片叶子,不是另外一片叶子?是通过它的形状,还是通过它的重量?

当我们在分布式环境中存储一些数据的时候,不得不面对的一个选择,就是ID生成器。

使用一个唯一的字符串,来标识一条完整的记录。

这时候,不能使用md5或者sha1来对整个记录做摘要,因为我们后续还要改动这个记录。也不能使用单机的计数器,因为计数器容易重启清零,也会存在多台机器上的数值重复,这违背了无状态服务的建设目标。

无奈的选择UUID

虽然UUID在大多数语言中都有相关的类库,但除非迫不得以,我们一般不会使用它。UUID虽然不会重复,但它非常的长,长的让人望而生畏。

XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

标准的UUID有5个部分组成:8-4-4-4-12,一共32个十六进制字符。因此,一共是128位。

当把UUID作为数据库的索引时,会因为它没有顺序性造成索引的随机分布和;因为数据量巨大造成查询性能降低。

同时,UUID也是不可读的。如果你把它打印在纸质的订单上,并不是一个好的主意。

UUID同时还有信息安全的隐患,它的数据计算里有MAC地址的参与,比较知名的是,曾被用于寻找梅丽莎病毒的制作者位置。

改造时间戳

如果你是单机应用,那么使用时间戳没什么问题,即使不用纳秒,使用毫秒也是足够的。但在分布式环境下面,时间戳同样不是一个好的选择。

即使你在机器安装了ntpd时间同步,但由于网络和机器的差异,计算机的时钟总是存在差异,你的时间戳总会出现重复。为了解决这个问题,你需要增加一些其他的标识,比如机器的ID,或者更多细分的信息减少时间的碰撞。

这种自定义的ID生成器,只适合特定的业务。

做着做着你就会发现,它本质上是雪花算法的变种。

雪花算法

雪花算法生成的ID是long类型,默认字符串长度是19位,它分为4个部分。

  1. 保留位 1 位。

  2. 毫秒时间戳 — 41 位(比如从现在开始,支持到未来的69年),这个其实也挺尴尬的,因为70年之后就会失效。但你不会在一家公司工作70年,所以,随它去吧。

  3. 配置的机器/节点/分片 ID — 10 位(总共支持 2^10 = 1024 个节点)

  4. 序列号 - 12 位(机器的本地计数,所以支持的并发已经很高了)

相比起UUID来,雪花算法所生成的ID是排序的,具有更好的紧凑性,是目前大多数业务优先采用的ID生成算法。

值得注意的是,雪花算法在JavaScript中有一个坑。后端在返回ID的时候,需要使用String类型代替Long类型,否则会产生预想不到的错误。

这是因为。在JavaScript中,存在两种数字。Number和BigInt。最常用的,就是number。

最大的Number,叫做Number.MAX_SAFE_INTEGER,它的值为:

  • 2^53-1 或者

  • +/- 9,007,199,254,740,991

众所周知,Java中的Long,是64位的。Js中的这个安全Integer,完全达不到Java中定义的长度。

这就是万恶的IEEE_754规范,它在Long长度大于17位时会出现精度丢失的问题。

NanoID

NanoID是从JavaScript库中演变过来的,目前在多个语言上通用。它长下面这样。

V1StGXR8_Z5jdHi6B-myT

虽然NanoID无法替代雪花算法,但就凭这长度,替换UUID是绰绰有余的。NanoID 大小只有 108 字节,比UUID小了35%,更加紧凑。

另外,它的速度更快,它可以使用默认字母表每秒生成超过 220 万个唯一 ID,使用自定义字母表时每秒可以生成超过 180 万个唯一 ID,且几乎没有碰撞几率。

如果你的ID对顺序性没有什么严格的要求,比如使用了kv等非常松散的数据库,那么NanoID是你的不二选择。

End

介绍了这么多,你会用哪种ID生成器呢?其实,一个组件如果使用的量增加到一定程度,都会出现问题,需要专门进行组件设计。

比如美团的leaf,在大型互联网中肯定有用武之地。但对于一般互联网,甚至是中型互联网来说,这到底是糖衣还是炮弹,作为决策者的你不得不思量思量。

我的新书《深入理解Java核心技术》已经上市了,上市后一直蝉联京东畅销榜中,目前正在6折优惠中,想要入手的朋友千万不要错过哦~长按二维码即可购买~

长按扫码享受6折优惠

往期推荐

一次简单的 JVM 调优,拿去写到简历里

高并发下如何防重?

入职就想run的公司特征

如果你喜欢本文,

请长按二维码,关注 Hollis.

转发至朋友圈,是对我最大的支持。

点个 在看 

喜欢是一种感觉

在看是一种支持

↘↘↘

注意:雪花算法并不是ID的唯一选择!相关推荐

  1. php绘制雪花墙,基于雪花算法的 PHP ID 生成器

    Snowflake 是 Twitter 内部的一个 ID 生算法,可以通过一些简单的规则保证在大规模分布式情况下生成唯一的 ID 号码. 其组成为: 第一个 bit 为未使用的符号位. 第二部分由 4 ...

  2. 基于雪花算法生成用户id

    8.1 为啥这样做 1.全局唯一性,不会出现重复的id.如果通过id自增来保证id不重复,则该表 无法分表操作例如 服务器A的数据库的user表 数据如下1 小明 男2 小红 女2 张三 男此时 进行 ...

  3. DefaultIdentifierGenerator 雪花算法 生成 重复 id 解决办法

    DefaultIdentifierGenerator 雪花算法 生成 重复 id 前言 问题发生 排查原因 问题解决 前言 利用 mybatisplus 的 DefaultIdentifierGene ...

  4. 雪花算法之唯一ID生成器理解

    雪花算法基本情况 雪花算法是一个分布式的唯一ID生成器. 它应该具有高并发,以及高性能优点. 基于时间戳,ID具有有序性,同时分布式下机器间时间差异过大(类似同一台机器时间回拨,一定会重复),会导致重 ...

  5. 推特雪花算法,分布式id生成器

    推特雪花算法 分布式id生成器 package util;import java.lang.management.ManagementFactory; import java.net.InetAddr ...

  6. 雪花算法【分布式ID问题】【刘新宇】

    分布式ID 1 方案选择 UUID UUID是通用唯一识别码(Universally Unique Identifier)的缩写,开放软件基金会(OSF)规范定义了包括网卡MAC地址.时间戳.名字空间 ...

  7. python版雪花算法生成唯一ID

    一.雪花算法图解 理论一大堆,总结如下图: 下方为源码,返回的结果为19位,为10进制表示,使用二进制表示就是64位,所以不必有所疑惑. 二.源码 1.异常捕获块 文件名:exceptions.py ...

  8. 雪花算法snowflake分布式id生成原理详解,以及对解决时钟回拨问题几种方案讨论

    文章目录 一.前言 二.雪花算法snowflake 1.基本定义 2.snowflake的优缺点 三.Java代码实现snowflake 1.组装生成id 2.计算最大值的几种方式 3.反解析ID 4 ...

  9. 分布式下使用雪花算法生成全局ID及解决时钟回拨问题

    简介 雪花算法是 64 位 的二进制,一共包含了四部分: 1位是符号位,也就是最高位,始终是0,没有任何意义,因为要是唯一计算机二进制补码中就是负数,0才是正数 41位是时间戳,具体到毫秒,41位的二 ...

最新文章

  1. LumaQQ.NET操作指令制作(3)
  2. 高通平台gpio简单调试
  3. Java算法-奇怪的分式
  4. 手动创建线程池 效果会更好_创建更好的,可访问的焦点效果
  5. java office在线编辑_国外10个最受欢迎的 Java 开发的 CMS 系统
  6. c语言大数的加减运算,求用C编个大数加减法运算程序
  7. AIX samba服务器配置
  8. api接口怎么对接_系统对接项目管理方面怎么做?从一次项目接口对接说起
  9. oracle authentication_services,理解SQLNET.AUTHENTICATION_SERVICES参数
  10. html th表格居中,HTML----之表格
  11. 只有20行Javascript代码!手把手教你写一个页面模板引擎
  12. Linux - CentOS基础
  13. 浅谈面粉厂防爆的重要性及措施(转)
  14. JSON 数据类型转换工具
  15. stagefright 流程解析
  16. AI 之父 | 图灵荣登 50 英镑钞票,荣耀比肩牛顿达尔文!
  17. R语言绘图—“金字塔图”
  18. 关于That command depends on command in Target ... script phase Copy Pods Resources报错解决方案
  19. 计算机基础知识及Linux高级运维基本命令
  20. IDEA默认JDK版本号变成11了

热门文章

  1. 每日三题 12.01
  2. 文件 备份 服务器失败怎么办,SMO“恢复服务器失败”从文件恢复备份
  3. 手写最大堆(Java实现)
  4. 网站因服务器原因被K站,如果网站被K怎么快速恢复
  5. 选择数据恢复软件如何避免踩坑?
  6. python比大小代码_Python中如何进行字符串比较大小?
  7. 六级备考28天|CET-6|听力第二讲|长对话满分技巧|听写技巧|2022年6月考题|14:30~16:00
  8. MATLAB窗函数法设计FIR 数字滤波器
  9. Word中还有空白突然整段跳到下一页
  10. html5c与vr哪个好,中兴Blade V8与小米5C对比评测:同档价格 骁龙435和澎湃S1谁更好?...