在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或者用作事务版本号、分布式链路追踪等等,好的全局唯一 ID 需要具备这些特点:
全局唯一:这是最基本的要求,不能重复;
递增:有些特殊场景是必须递增的,比如事务版本号,后面生成的 ID 一定要大于前面的 ID ;有些场景递增比不递增要好,因为递增有利于数据库索引的性能;
高可用:如果是生成唯一 ID 的系统或服务,那么一定会有大量的调用,那么保证其高可用就非常关键了;
信息安全:如果 ID 是连续的,那么很容易被恶意操作或泄密,比如订单号是连续的,那么很容易就被看出来一天的单量大概是多少;
另外考虑到存储压力,ID 当然是越短越好。
那么分布式场景下有哪些生成唯一 ID 的方案呢? 01利用数据库生成 先说最容易理解的方案,利用数据库的自增长序列生成:数据库生成唯一主键,并通过服务提供给其他系统;如果是小型系统,数据总量和并发量都不是很大的情况下,这种方案足够支撑。 如果每次生成一个 ID 可能会对数据库有压力,可以考虑一次性生成 N 个 ID 放入缓存中,如果缓存中的 ID 被取光,再通过数据库生成下一批 ID 。
优点:理解起来最容易,实现起来也最简单。
缺点:也非常明显了,每种数据库的实现不同,如果数据库需要迁移的话比较麻烦;最大的问题是性能问题,并发量到一定级别的时候这个方法估计会很难满足性能需求;另外通过数据库自增生成的 ID 携带的信息太少,只能起到一个标识的作用,同时自增 ID 也是连续的。