分布式唯一ID

唯一id的四个要求

  • 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。
  • 趋势递增:在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用B+ tree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。
  • 单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序等特殊需求。
  • 信息安全:如果ID是连续的,恶意用户的扒取工作,比如爬订单号,对手可以直接知道我们一天的单量。
  • 在一些应用场景下,会需要ID无规则、不规则。

UUID

  • 介绍
    • UUID(Universally Unique Identifier)的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,示例:550e8400-e29b-41d4-a716-446655440000
  • 优点
    • 性能非常高:本地生成,没有网络消耗。
  • 缺点
    • 存储不方便:UUID太长了,没有合适的数据可以表示128位的数字,因此通常用长度为36的string类型表示,这会占用36 bytes
    • 信息不安全基于MAC地址生成UUID的算法可能会造成MAC地址泄露。
    • 无序:UUID并不能保证顺序

雪花算法

  • 不依赖于数据库,强依赖于时间戳
  • 只需要用一个long类型就可以表示,从现在看开始,41位时间戳可以表示 2 31 2^{31} 231秒,一天是86400秒,这样算起来,差不多就是 2 16 ∗ 1.5 2^{16}*1.5 2161.5的样子,所以可以表示大于 2 1 4 = 16384 2^14=16384 214=16384天,因此至少是60年(实际上是69年),基本上没有任何一款应用可以撑到69的
  • 1符号位+41位的毫秒时间戳+5位机房号+5位机器号+12位毫秒内自增id
  • 当机器故障,发生时间回迁的时候,很可能会出现重复id,不能完全保障可重复性
  • 具体实现的时候,一旦发生时间回迁,就会抛出异常,这会导致不可用
  • 实现
/** 
 * SnowFlake的结构如下(每部分用-分开)
 * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 
 * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0 
 * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
 * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。
 *
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值