对飚雪花ID,高并发下唯一订单号生成器

背景

产品需求是为订单生成一个10位长度的订单号,可以包含字母和数组,字母不区分大小写。

  • 方案一: 利用mysql自增,但是最多也就是10 0000 0000,这个可怎么办?

  • 方案二:随机生成10位随机数+字母组合,如何保证唯一性?每次插入前去数据库里遍历还是利用唯一索引?
    这个方案好像也不好,数据量大了效率很低?而且完全随机,没有递增型。

  • 方案三:其他主键+序列号
    比如订单号= 分类号+日期+序列号(累计)
    这个是能满足一些数据量不大的情况,如果没有一个分类一天销售很多流量也是有问题的。而且订单号并没有单调递增。

我们仔细分析分析需求,10位订单号比较短,想保持唯一性不容易,你想想时间戳精确到秒都10位了。我们还要保持单调递增,又不能让人轻易猜出每天多少订单量。

我们可能想到雪花ID,是的,雪花ID设计很巧妙,但是长度太长不满足产品的需要,不过我们可以对雪花ID改造。

0000 0000		0			0
时间戳			机器ID		序列号

我们把10位分为3组:

第一组是前8位用做时间戳,由于是字母+数字组合,所以一位就能表示36个数字,0-9a-z,也就是36进制,36^8 = 2821109907456 毫秒 > 89年 * 365 * 24 *3600 * 1000
也就是精确到毫秒能用89年,不错啦。

第二组是机器ID,也是36进制,能用36个实例,基本够了。

第三组是序列号,也是36进制,那一个实例一毫秒最多36个订单号。

我们不难看出这不就是雪花的ID的变形吗,只不过我们支持字母+数字组合,所以就能缩小一些位数,是的,没错!

功能

我们再来看看上面我们提出的方案,基本能满足并发量不大的需求,当并发量实在太多可以多创建几个实例,一毫秒需要的订单号超过36个,那就再等下一毫秒呗。

如果就要钻牛角尖,就不愿意等下一毫秒,那我们就要对扩大第三组的限制了,如果再扩大一位就能每毫秒36X36=1296个了,如果再扩大一位那就能一毫秒36X36X36=46656个了,如果还不满足还可以继续,但是我觉得意义不大了。

扩展倒是很容易,但是产品得统一订单号位数变长啊,有的能同意,有的就难沟通了,所以这里我打算把每毫秒的最多数量做成能动态设置的。

另外,我们上面提到我们能用89年,如果从1970年开始那我们也就是能用到2059年,那很快了啊,怎么办?其实我们大可不必从1970年开始,从2000年开始不香吗?从2020年开始不更香吗?
这里我也打算做成可设置的,只是要注意下,项目开始就要决定从哪年开始,不然来回变化有可能重复咯。

使用

这里我们给出go版本的使用,很简单,https://github.com/xingliuhua/leaf

go get github.com/xingliuhua/leaf
	err, node := leaf.NewNode(0)
	if err != nil {
		return
	}
	// 每毫秒200个
	err = node.SetGenerateIDRate(200) 
	if err != nil {
		return
	}
	startTime := time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).UnixNano() / 1000000
	// 从2020年开始
	err = node.SetSince(startTime)
	if err != nil {
		return
	}
	for i := 0; i < 40; i++ {
		err, id := node.NextId()
		if err != nil {
			return
		}
		fmt.Println(id)
	}

当然node.SetSince,node.SetGenerateIDRate方法都可以不写,使用默认的也可以。

总结

站在巨人的肩膀上,我们能看得更远,说是对飚雪花ID,其实就是借鉴的雪花ID,大家也可以根据自己的需求自己实现雪花ID。

最后能帮忙点个star吗?
https://github.com/xingliuhua/leaf

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值