雪花算法之【线上订单号重复了一招搞定它!】

雪花算法之【线上订单号重复了一招搞定它!】,第1张

公司老的系统原先采用的时间戳生成订单号,导致了如下情形

打断一下:大家知道怎么查系统某项重复的数据吧

不得了,这样重复岂不是一单成功三方回调导致另一单也成功了。

多个服务怎么保证生成的订单号唯一呢?

先上code

以上是采用snowflake算法生成分布式唯一ID

41-bit的时间可以表示 (1L<<41)/(1000L360024365)=69 年的时间,10-bit机器可以分别表示1024台机器。如果我们对IDC划分有需求,还可以将10-bit分5-bit给IDC,分5-bit给工作机器。

这样就可以表示32个IDC,每个IDC下可以有32台机器,可以根据自身需求定义。12个自增序列号可以表示 2^12 个ID,理论上snowflake方案的QPS约为 4096w/s ,这种分配方式可以保证在任何一个IDC的任何一台机器在任意毫秒内生成的ID都是不同的。

这种方式的优缺点是:

优点:

缺点:

一般来说,采用这种方案就解决了。

还有诸如,mysql的 auto_increment策略,redis的INCR,zookeeper的单一节点修改版本号递增,以及zookeeper的持久顺序节点。

关于雪花ID算法的介绍有很多文章,就不画蛇添足了,当然雪花ID算法也有一个问题是时间回拨的问题,这个可以参考以下两个链接去了解:

>

它的时间判断参数是一个成员变量,生命周期跟着当前类走。而调用的方法并不是个单例模式,所以每次新建一个对象,其内部判定的时间判断参数都是独立存在的,这样的话在并行程序的过程中,是有可能生成相同的id的。原本怀疑是否是使用了java8的stream的原因。然而发现,人家默认就是串行流,要使用并行流是需要而外加方法的,所以和这个没有关系。

解决方法,写一个IdentifierGeneratorutil,既然DefaultIdentifierGenerator的Sequence不是单例,那么我们就在外层做 *** 作,把调用到的IdentifierGenerator变成单例。IdWorker这个类是MyBatisPlus雪花算法的实现,直接调用其方法获取,它内部是单例实现的。ps(若没有特殊需求,用官方提供的就好了)。雪花算法的原始版本是scala版,用于生成分布式ID(纯数字,时间顺序),订单编号等。最高位是符号位,始终为0,不可用。41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。10位的机器标识,10位的长度最多支持部署1024个节点。12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。

1 星型模式

星形模式(Star Schema)是最常用的维度建模方式。星型模式是以事实表为中心,所有的维度表直接连接在事实表上,像星星一样。星形模式的维度建模由一个事实表和一组维表成,且具有以下特点:a 维表只和事实表关联,维表之间没有关联;b 每个维表主键为单列,且该主键放置在事实表中,作为两边连接的外键;c 以事实表为核心,维表围绕核心呈星形分布;

2 雪花模式

雪花模式(Snowflake Schema)是对星形模式的扩展。雪花模式的维度表可以拥有其他维度表的,虽然这种模型相比星型更规范一些,但是由于这种模型不太容易理解,维护成本比较高,而且性能方面需要关联多层维表,性能也比星型模型要低。所以一般不是很常用

雪花模式

3.星座模式

星座模式是星型模式延伸而来,星型模式是基于一张事实表的,而星座模式是基于多张事实表的,而且共享维度信息。前面介绍的两种维度建模方法都是多维表对应单事实表,但在很多时候维度空间内的事实表不止一个,而一个维表也可能被多个事实表用到。在业务发展后期,绝大部分维度建模都采用的是星座模式。

星座模型

以上就是关于雪花算法之【线上订单号重复了一招搞定它!】全部的内容,包括:雪花算法之【线上订单号重复了一招搞定它!】、修改redis zset的score为64位整形以支持雪花ID算法、雪花算法生成id重复的坑等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10204394.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存