支持分库分表的分布式ID生成规则

在分布式环境中的系统,全局唯一ID生成的设计尤为重要。每个公司都会根据自身实际情况,设计出针对自身环境的唯一ID的系统。

一、MongoDB的ObjectID:

开源软件也不例外,MongoDB是一款支持分布式环境(Shard)的非关系型数据库,在分布式全局唯一ID生成的设计上有哪些值得学习的地方呢?

首先,我们看一下官方对BSON ObjectID的解释(Learn more from ObjectId):

ObjectID是一个用16进制字符表示的,总长度为12Bytes的字符串。

分别由4字节时间戳+5字节进程唯一ID+3字节的计数器,这样便保证了在分布式环境中且多个进程生成的ID是唯一的。

但是如果要以这样一个12Bytes的字符串来进行分库分表的操作,该怎样计算呢?我们完全可以按照ObjectID的设计思路,来设计一个64Bit的整形ID。

二、64Bit(8Bytes)分布式ID的设计:

64Bit最大取值:

生成的规则可以是: ID = Unix Timestamp[32Bit] + (机器识别号 + 额外数据 + 秒内顺序号)[<32Bit]

其中 (实例ID + 额外数据 + 增序码) 不超过32Bit。

这样的设计不仅可以达到分布式唯一的要求,还可以根据[额外数据]这一项来扩展使用。

比如,有这样一个要求,生成一组订单号,根据用户ID分1024个表,需要根据用户ID查找到库中该订单号的数据,也可以根据订单号查找到数据。

生成ID:
根据用户ID读库:
根据订单号读库:

这样的设计可以保证:

  • 分布式环境中,每个机器生成的ID都是不同的。
  • 同一个机器,每秒内,以顺序号递增确保生成的ID是唯一的。
  • 将时间戳放在最高位,生成的ID呈整体递增趋势。
  • 单台机器最大生成速度可以达到 16383条/s,可以满足高并发需求。
  • 可以满足支持bigint(int64)数据库,如Mysql。
  • 可以满足支持两个维度进行查询的分表需求。

缺点:

  • 无法确保绝对递增,因为不能确保每台服务器的时间一致,也无法确保同一时间内机器识别码小的机器先生成。

猜你喜欢:

发表评论

电子邮件地址不会被公开。 必填项已用*标注