码迷,mamicode.com
首页 > 其他好文 > 详细

网易云课堂-分布式订单号生成策略

时间:2020-04-26 21:15:22      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:算法   机器   pre   set   限制   rem   参数   缺点   字符   

订单号要求

  • 全局唯一
  • 长度固定
  • 趋势递增
  • 高并发
  • 高效率(整型、不能太长)

策略一:UUID

  • 缺点:无序、效率低、字符串、过长(占用空间)、可读性差

策略二:数据库自增

  • 自增参数设置
    show varivables like ‘auto_inc‘;
    -- 起始
    set @@auto_increment_offset=2
    -- 步长
    set @@auto_increment_increment=5
    
  • 可通过设置不同数据库自增参数来并发获取订单号
  • 缺点
    • 不利于数据库服务器伸缩(步长限制)
    • 不利于数据迁移

策略三:雪花算法

  • SnowFlake:最原始的版本来源于Twitter,是用Scala实现的。地址为 https://github.com/twitter-archive/snowflake。

  • SnowFlake:是一个64bit的整数分别由四部分组成: 1(最高位固定为0表示整数)+41(时间戳以毫秒为单位)+10(机器编号用来区分不同服务器)+12(序列号,同一毫秒同一机器可支持4095个序列号)。
    技术图片

  • 根据源码可知最后的结果是由时间戳,机器码,工作码,序列数位或运算(|)得到的结果。

    • 时间戳:时间戳等于当前时间戳减去开始计算时间然后左位移偏移量。偏移量等于12+5+5。
    • 机器码:-1L^(-1L <<5L),首先-1左移5位得到的结果再和-1异或计算,得到的结果是31,也就是5位能表达出的最大正整数。然后随机机器码再向左偏移12+5得到机器码。
    • 工作码:工作码和机器码类似,只是最后向左偏移量是5。
    • 序列码:序列是从0开始的自增序列,他是12位的最大整数 4095,从源码可以看出如果是同一毫秒,序列号要自增,如果是新的毫秒序列号要从0开始重新计算。sequence=(sequence+1)&sequenceMask可以保证不管sequence传入多少都能保证最后的结果小于4095,这样可以达到防溢出的效果。
  • 缺点:依赖服务器时间,id递增规律,可能因此泄漏商业机密(根据订单ID猜出订单量);长度长且固定,不容易加入自定义变量

策略四:基于redis自增

  • 思路:利用增长计数API,结合其他信息组成唯一ID
  • Redis的 incr(key) API
    技术图片
  • 缺点:
    • 引入第三方依赖
    • 增加网络开销
    • 服务器成本、维护开销(redis高可用、集群)

总结

  • 没有银弹,根据场景和需求选择合适的,满足KISS原则即可

网易云课堂-分布式订单号生成策略

标签:算法   机器   pre   set   限制   rem   参数   缺点   字符   

原文地址:https://www.cnblogs.com/wod-Y/p/12781906.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!