简介

对大量数据进行唯一标记,唯一标记的生成成为关键

要求

  • 全局唯一性
  • 趋势递增(数据库主键索引结构为B-TREE,应该有序保证写入效率)
  • 单调递增
  • 不暴露业务信息
  • 低延迟、高可用、高并发

方案

  • UUID
  • 数据库、Redis等单点服务
  • 类snowflake算法

UUID

UUID大家都很熟悉了,这里只介绍一下优缺点

  • 优点:
    • 本地产生,无远程调用,延迟低
    • 容易拓展,每台机器都可以直接使用
  • 缺点:
    • 无序,无法成为主键
    • 不同机器实现方式不一致可能重复
    • 信息不安全,基于MAC地址产生的可能造成MAC泄漏

单点服务

使用数据库或者Redis等单点服务生成递增的id

  • 优点:
    • 简单方便
    • 全局单调递增
  • 缺点:
    • 强依赖单点服务
    • 性能限制于单点服务
    • 难以拓展

优化一 高可用单点服务,可能导致主从切换时重复id
优化二 使用多个机器,设置不同初始值,步长为机器总数,可能导致水平拓展困难、失去单调递增性、性能依旧限制于机器个数
优化三 每次从数据库取一个id段,id段使用完毕再从数据库再取一段,可能导致id不够随机、tps达到id段个数时出现性能尖刺、DB宕机无法使用
优化四 在优化三的基础上,本id段使用一定比例再取一个id段,id段使用完毕可以直接切换到下一个id段,避免尖刺,可能导致DB宕机无法使用

类snowflake算法

雪花算法大家也比较熟悉了,下面是雪花算法的id组成结构,这里谈一下优缺点和需要解决的核心问题

雪花算法id组成结构

  • 优点:
    • 趋势递增
    • 不依赖第三方,高可用,高并发(每一毫秒单机4096个id)
    • 可修改每段bit个数适应应用系统
  • 缺点:
    • 趋势递增,非单调递增
    • 强依赖时钟,时间回拨导致服务不可用或id重复
    • 并发较小时,末尾为0的机率很大,分库分表取模后不均匀

解决时钟回拨问题

  • 启动时判断自身时间与上次记录时间
  • 启动时判断自身时间与其他机器时间平均值
  • 每隔一段时间写入时间记录
  • 每次生成id都与上次时间比较
  • 时间较大回拨直接启动失败或停止服务
  • 时间较小回拨可以等待

参考文档

Leaf——美团点评分布式ID生成系统
【分布式全局ID】细聊分布式ID生成方法