分布式id

发布时间 2023-07-30 23:10:57作者: RainbowMagic

自增id

b + 树节点是有序的,所以id最好也是有序的,这样存储数据效率高一点,如果不是递增的,那讲数据存储到数据库中效率较低,还得找树的值,递增的话直接按id插入到树中即可,而乱序则还得找相应的位置才能进行插入。

  • 趋势递增:总体来看顺序是递增的。
  • 单调递增:下一个一定比上一个大。
  • 信息安全:如果id是连续的,那么恶意用户可以根据id来判断 出总体数据量大小。

UUID

性能较高,jdk本地类就可以自己生成
缺点:

  • 长度太长,在Mysql中存储的长度越短效率越高,存储到MySQL中效率较低
  • UUID是无序的。存储到MySQL中还得计算树节点的位置,所以效率较低,不适合互联网。
  • 不安全,可以根据UUID获取到MAC地址,最新版好像已经解决了这个问题。
  • 无法进行范围查询。

雪花算法

image
1bit: 符号位,不做处理。
4bit: 时间戳,单位是毫秒。
10bit: 工作机器id,一般是这样用的: 前五位用来表示机房id,后五位来表示每个机房下的每台机子的id,具体问题具体分析,根据项目的不同,自定义的操作也不同。
12bit: 自增id,每毫秒能生成2^12个不同的id。

优点:

  • 递增
  • 安全 没办法根据时间范围判断出记录条数,每毫秒可以生成2^12个id,但是不是每毫秒都能生成这么多id。

缺点:

  • 由于雪花算法是根据时间戳来生成id的,所以如果时间回拨的话,可能会出现重复的问题。在日常使用计算机的过程中,计算机会定时去向服务器去同步时间,如果服务器时间与本地时间不同的话会进行设置,这时候可以出现回拨,因为CPU是通过震荡来计算当前时间的,一旦运行时间过长,那么会有误差,所以需要与服务器同步。

雪花算法变种

百度uid generator

github: https://github.com/baidu/uid-generator

分布式id服务

MySQL

之前所说的MySQL自动生成的id是无法生成全局唯一id的,所以我们可以新建一张表,中的其中一个字段专门生成id,其他表需要使用id的时候直接去这张表中获取,这样就能保证了全局唯一id。
MySQL对数据进行读写时需要对磁盘进行io,磁盘io性能并发较差。每次业务操作都需要读写一次数据库表,数据库压力会很大。
可以加MySQL 副本来增加服务器,根据服务器的不同,生成不同的id,例如有两台MySQL服务器,一台服务器生成偶数id,一台服务器生成奇数id。

Redis

redis也可以实现这个操作,只要专门设置一个key了存储自增id,每次获取id的时候,直接进行自增即可。redis原子性且性能号。
由于redis是内存数据库,一旦服务down调,那么服务器中保存的id会消失,而redis的持久化机制是根据规则来进行持久化,在持久化的过程中,每到达规则,这时候挂掉,每持久化数据,那么id就会丢失一部分,id可能会出现重复。

分布式id微服务

美团leaf

美团在雪花算法中进行了加强,