全局唯一id生成方案

方案没有好坏,只有适合与否

依赖第三方机制

mysql主键自增

  • 优点
    – 简单方便
  • 缺点
    – 扩容复杂,业务增大时候迁移困难等

基于时间戳+随机数

  • 优点:
    – 流水号对人比较友好,可方便看到生成时间
  • 缺点(随机数生成需要校验前面是否生成过)
    – 可将生成值写入redis的set集合中
    – 或者使用redis自增等

UUID

  • 优点
    – 简单粗暴
  • 缺点
    – 比较长,占用空间大,无序

redis自增

  • 优点
    – 适合每天订单从0开始
  • 缺点
    – 强依赖redis,主要看redis机器能抗住多少量

依赖算法实现

Twitter-Snowflake算法

实现原理:将long64位进行拆分
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
1位:表示正负,状态位,可不使用
41位:时间戳=(当前时间-上线时间)的毫秒数 ,这个长度可以使用69年
2^41/365/24/60/60/1000=69.7
10位:5位表示机器中心,5位表示机器ip,不超过1024个节点
12位:每毫秒内产生的流水号,不超过2^12=4096个数

  • 优点
    – 不依赖数据库,性能高于数据库,在单机上产生是有序的
    – 灵活,如果并发量比较大,可将节点
  • 缺点
    – 由于分布式,无法做到全局递增

微信id生成算法

曾钦松的文章,很详细

实现原理简述:
1.内存中储存最近一个分配出去的sequence:cur_seq,以及分配上限:max_seq
2.分配sequence时,将cur_seq++,同时与分配上限max_seq比较:如果cur_seq > max_seq,将分配上限提升一个步长max_seq += step,并持久化max_seq
3.重启时,读出持久化的max_seq,赋值给cur_seq,带来的问题是重启磁盘io的问题,引入号段的概念,多人使用一个max_seq

  • 优点
    – 系统吞吐量很高,生成id也很多,是Snowflake的变种,可将机器节点持久化在db中,这样产生的id可以很多,以单节点单分钟100w来计算,可使用2^64/365/24/60/60/100w=292471年
  • 缺点
    – 分布式生成,无法全局递增

总结

全局唯一id生成算法多种多样,适合业务用最小的成本才是最好的。Snowflake算法很优秀,中间还有许多细节点,这里前人有例子
从一次snowflake异常说起
引发原因是时间戳相同,机器位是使用ip全部二进制后取10位,结果不巧两个ip的值计算结果相等,在低并发情况下,有可能值相等。

你可能感兴趣的:(java,调试)