分布式|微服务

9次阅读
没有评论

分布式 id 生成方案

分布式 ID 需满足唯一性、有序递增性、高可用性、带时间性。

  • UUID:通过本地算法生成,结合网卡、时间和随机数
    • 本地生成,生成简单,性能好,没有高可用风险
    • 但长度长、不可读、查询效率低。
  • 数据库自增 ID:使用数据库的 id 自增策略,如 MSQL 的 auto increment。并且可以使用两台数据库分别设置不同步长,生成不重复 ID 的策略来实现高可用。使用数据库自增 ID,绝对有序,高可用
    • 数据库生成的 ID 绝对有序,高可用实现方式简单
    • 需要独立部署数据库实例,成本高,有性能瓶颈,效率较低
  • 批量生成 ID:一·次按需批量生成多个 ID,每次生成都需要访问数据库,将数据库修改为最大的 ID 值,并在内存中记录当前值及最大值。
    • 避免了每次生成 ID 都要访问数据库并带来压力,提高性能
    • 属于本地生成策略,存在单点故障,服务重启造成 ID 不连续
  • Redis 生成 ID:Redis 的所有命令操作都是单线程的,本身提供像 incr 和 increby 这样的自增原子命令,所以能保证生成的 ID 肯定是唯一有序的。
    • 不依赖于数据库,灵活方便,且性能优于数据库; 数字 ID 天然排序,对分页或者需要排序的结果很有帮助。
    • 如果系统中没有 Redis,还需要引入新的组件,增加系统复杂度; 需要编码和配置的工作
    • 量比较大。
  • 雪花算法: 推特公司发明,基于时间戳、机器位和序列号生成,高性能、低延迟、有序,一般不会重复。
    • 高性能,低延迟,按时间有序,一般不会造成 ID 碰撞 (每毫秒有 4096 个 id)
    • 需要独立的开发和部署,依赖于机器的时钟
    • bigint,19 位纯数字,对于前端会出现精度缺失的情况
  • 百度 UidGenerator
    • 标准雪花算法最怕时钟回拨(时间倒流),会导致 ID 重复。
    • 时间戳秒级 :标准雪花是毫秒级,百度改为秒级,节省了位数。
  • 美团 Leaf
    • Leaf-segment(号段模式):不依赖时间戳。从数据库批量取出一批 ID(如 1000 个)缓存在本地
    • Leaf-snowflake:标准雪花算法的改进版。使用 Zookeeper 来管理 WorkerID
  • ULID (Universally Unique Lexicographically Sortable ID)
    • 格式 :48 位时间戳 + 80 位随机数。
    • 编码 :使用 Crockford’s Base32 编码(只包含 0-9 和 A-Z,排除了 I, L, O, U 避免混淆)。
    • 字符串有序 :按字符串字典序排序等于按时间排序(这点雪花算法的 Base64 编码做不到)。
    • 长度 26 字符 (16 字节)
    • 不需要机器节点 id
  • TSID (Time-Sorted Identifier)
    • 结合了 Twitter 雪花算法和 ULID 的特点。
    • 格式 :通常也是字符串形式,兼顾时间排序和唯一性。
    • 特点在于它试图在保持排序的同时,提供比 ULID 更好的物理存储特性(有些实现会尽量让 ID 长度更短)。
    • 长度 13 字符 (8 字节)
    • 需要机器节点 id
  • MongoDB ObjectId
    • MongoDB 默认的主键 ID,也是一种类雪花算法。
    • 格式 :12 字节的十六进制字符串(24 个字符)。
    • 组成 :4 字节时间戳 + 3 字节机器 ID + 2 字节进程 ID + 3 字节计数器。
    • 特点 :天生分布式,无需配置,按时间大致有序。

<br/>

事务的报错和版本回滚

  • 在正常的订单流程重,库存扣减成功,用户服务成功,但是在生成订单的过程失败了
  • 在积分消费中,用户 1000 积分消费 700 积分,过程中又消费了 300 积分购买商品,但是在消费 700 积分的扣减过程订单失败,事务要进行回滚返回到 1000 积分,多给了用户 300 积分
  • 例如在上面的积分中,店铺手动给用户添加 2000 积分,积分回滚的时候要保证 2000 积分的添加
正文完
 0
评论(没有评论)
验证码