{eval=Array;=+count(Array);}

问答专栏Q & A COLUMN

高并发下如何生成唯一订单号?

sunnyxdsunnyxd 回答0 收藏2
收藏问题

10条回答

worldligang

worldligang

回答于2022-06-28 15:43

互联网架构


分布式/集群环境ID生成要求

  1. 全局唯一
  2. 高并发支持
  3. 高可用
  4. 趋势递增
  5. 信息安全
  6. 可读性

ID 生成策略

1、UUID

  1. 通用唯一识别码
  2. 组成: 当前日期 + 时间 + 时钟序列 + 机器识别码(MAC地址或其他)
  3. 在分布式系统中,所有元素都不需要通过中央控制端来 判断数据的唯一性

2、数据库自增

  • 关系型数据库都实现数据库自增ID;Mysql通过AUTO_INCREMENT实现、Oracle通过Sequence序列实现。
  • 在数据集群环境下,不同数据库节点可设置不同起步值、相同步长来实现集群下生成全局唯一、递增ID
  • SET GLOBAL auto_increment_increment = 3
  • SET GLOBAL auto_increment_offset = 1;


3、Snowflake

  • 41位时间戳+10位机器ID +12位序列号(自增),转换为长度为18的长整型
  • Twitter为满足每秒上万条消息的创建,每条消息都必须分配全局唯一ID,这些ID需要趋势递增,方便客户端排序。


4、Redis

  • Redis 实现自增ID
  • Redis实现了incr(key) API用于将key 的值递增1,并返回结果,如果key不存在,则创建并赋值为0,然后再执行incr操作。

几种策略总结


评论0 赞同0
  •  加载中...
lewinlee

lewinlee

回答于2022-06-28 15:43

生成全局唯一ID有以下几种方式:

时间戳+用户ID+随机数

这其实并不是真正意义上的全局唯一ID,但是在并发量不高的场景中已经够用了。其中时间戳可以是毫秒级别

UUID

这种方式比较方便,有现成可用的JAR包,但是也有缺点:ID可读性不好,而且会造成索引树频繁页分裂,影响数据库性能和空间使用


数据库序列表

维护一张序列表。考虑到性能问题,不必每次生成ID都去操作数据库,可以设置一定的步长比如1000,每次从表中拿1000个序列号,从每台服务器内存中线性去取


Redis

维护一个序列号键值对,利用Redis自增的原子性,生成序列号


Snowflake

同一毫秒可以产生ID数量4194304个,优点是完全内存操作性能好,缺点是依赖于系统时钟一致性。如果某台机器的系统时钟回拨,有可能造成ID冲突,或者ID乱序


总结

最重要的还是根据项目的场景,尤其是并发量,选择最合适的方法


敬请关注

请点击关注按钮【IT徐胖子】会持续为大家奉献互联网和技术干货内容,感谢支持

评论0 赞同0
  •  加载中...
fxp

fxp

回答于2022-06-28 15:43

由于是高并发情况,所以不建议使用数据库自增ID,可以参考如下方案:

1、redis自增id

2、UUID

3、时间戳+随机数

4、Twitter的snowflake算法

5、利用zookeeper生成唯一id,性能不如redis

6、MongoDB的ObjectId,和snowflake算法类似

评论0 赞同0
  •  加载中...
cheukyin

cheukyin

回答于2022-06-28 15:43

雪花算法足够了。我这边两个业务线都是用的雪花算法 完全能保证唯一。

评论0 赞同0
  •  加载中...
neroneroffy

neroneroffy

回答于2022-06-28 15:43

随便哪个程序员都可以写出来一个生成订单的算法,除了美团、淘宝这种需要考虑订单重复,大多数企业还是发愁没有订单的状态,需要考虑这个问题的企业应该不差钱了,希望我的公司有机会让我来解决这个问题。

评论0 赞同0
  •  加载中...
leeon

leeon

回答于2022-06-28 15:43

1:获取当前日期作为订单号的前8位

2:获取uuid,它是通用唯一识别码,进行hashcode转码仍然可以保证其唯一性,可以取12位

3:日期和uuid转码之后的12位拼接,一共20位,可以生成唯一订单号

评论0 赞同0
  •  加载中...
zxhaaa

zxhaaa

回答于2022-06-28 15:43

最简单的办法就是用用户名➕ip➕时间生成订单号,然后计算哈希值后做一定转换就可以生成唯一订单号。不过唯一的问题就是不太好查。毕竟这种订单号没有任何规律可言,后期查询是个大麻烦。其实最建议的方式就是分渠道分地区建立订单号。就和身份证号生成机制一样,各个地区可以独立生成身份证号,最后合在一起还没有任何问题。

评论0 赞同0
  •  加载中...
animabear

animabear

回答于2022-06-28 15:43

用算法呀。对订单这种,很简单。

商品id +用户id+时间戳+随机数+自增数

就能保证唯一性。现实中,没哪个用户去高并发下单(除非bug)。

评论0 赞同0
  •  加载中...
2501207950

2501207950

回答于2022-06-28 15:43

雪花算法 有开源实现

评论0 赞同0
  •  加载中...
jonh_felix

jonh_felix

回答于2022-06-28 15:43

看一下美团的leaf

https://tech.meituan.com/2019/03/07/open-source-project-leaf.html

评论0 赞同0
  •  加载中...

相关问题

最新活动

您已邀请0人回答 查看邀请

我的邀请列表

  • 擅长该话题
  • 回答过该话题
  • 我关注的人
向帮助了您的网友说句感谢的话吧!
付费偷看金额在0.1-10元之间
<