分布式系统id生成方案分析

一、分布式系统的id 生成

分布式id 需要保证全局唯一,在此基础上 尽可能的保证有序,语义性。

有序性是为了匹配mysql 总innodb引擎的 数据存储结构
语义性是便于查找问题,例如从id 中可以辨识出业务类型,时间等信息。

二、UUID 分析

UUID 是一种过去比较流流行的分布式id 生成方案,使用方式简单,Mybatis-plus 内置了UUID 主键生成器。

UUID 可以保证唯一性,但是没有顺序,更没有语义含义。

在分布式系统中 UUID 虽然可以使用,但是影响了mysql 数据写入性能。

这个已经不推荐使用了。

三、Snowflake

Twitter 早期开源了Snowflake 的相关方案 是目前应用相对比较广泛的一种方式。

MongoDB 的ObjectId

微信的seqsvr

具体实现每种方案有自己的逻辑,但是本质相同

Snowflake 可以保证唯一性,还能保证顺序,另外具备一定的语义性。

3.1Snowflake 的注意点

1 时间变化

Snowflake 依赖于时间计算,所以你需要保证你的分布式集群机器的是时间一直,否则一定概率会出现重复的id.

那么怎么保证所有的机器时间一致呢,这似乎是一个操作系统层次的问题

推荐一篇论文

Lamport 《Time,Clocks,and the Ording of Events in Distributed System》

Twitter 在文档中建议开启NTP

另外一个国内容易忽略的 是冬时令 切换。

冬时令

当时钟拨慢一个小时,也一定程度会出现重复id

2 id 的可预测性

在安全领域,如果黑客能预测或者伪造id 的时候 ,风险便会暴露,例如 生成token的时候,

Erlang 的版本 的flake基于MAC 地址计算,信息也比较敏感。

3时间位数的限制

一些Snowflake 的时间位数有限制,会在有限的时间内耗尽。

时间戳会一直增加,即使一段时间内没有数据进入,该区间的值也不可用了。

不过这一点可以通过自己实现Snowflake 来实现,根据业务实际生产可预测的未来id。

4 Linux 时间漂移

这个问题类似于 时间变化

linux系统有两个时钟:一个是由主板电池驱动的“Real Time Clock”也叫做RTC或者叫CMOS时钟,硬件时钟。当操作系统关机的时候,用这个来记录时间,但是对于运行的系统是不用这个时间的。另一个时间是 “System clock”也叫内核时钟或者软件时钟,是由软件根据时间中断来进行计数的,内核时钟在系统关机的情况下是不存在的,所以,当操作系统启动的时候,内核时 钟是要读取RTC时间来进行时间同步(有些情况下,内核时钟也可以通过ntp服务器来读取时间)

这两个时钟通常会有一些误差,所以长时间可以导致 这两个时钟偏离的比较多,最简单的保持两个时间同步的方法是用软件测出他们之间的误差率,然后用软件进行修正。在每次重新启动系统的时候,系统都会用 hwclock命令对时间进行同步。如果内核时钟在每一个时间中断都快或者慢的话,可以用adjtimex命令进行调整,使得RTC和内核时间走的快慢一 致。

四、业务系统的id 检测

简单的理解就是 业务系统拿到id 之后不要着急用,在业务逻辑进行检测一下 是够有重复的id

如果有则丢弃。

这种严谨的逻辑 可以保证id唯一,但是同时增加系统的复杂性,这个大家可以根据自己的业务实际考量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值