使用雪花算法生成ID

常见的生成主键id的方式

生成主键方案:

  • UUID
  • 数据库自增主键
  • 基于Redis生成全局ID策略
  • 雪花算法,Twitter的分布式自增ID算法snowflake
  • 百度UidGenerator算法(基于雪花算法实现自定义时间戳)
  • 美团Leaf算法(依赖于数据库,ZK)

雪花算法的优缺点

优点

  1. 经测试snowflake每秒能生成26万个自增可排序的ID。
  2. snowflake生成的ID结果是一个64bit大小的整数,为一个Long型 (转换成字符串后长度最多19)。
  3. 分布式系统内不会产生ID碰撞(datacenter和workerId作区分)并且效率高。
  4. 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也非常高,可以根据自身业务分配bit位,非常灵活。

缺点

  1. 时间回拨问题:由于机器的时间是动态的调整的,有可能会出现时间跑到之前几毫秒,如果这个时候获取到了这种时间,则会出现数据重复。
  2. 机器id上限:机器id是固定的bit,那么也就是对应的机器个数是有上限的,在有些业务场景下,需要所有机器共享同一个业务空间,那么10bit表示的1024台机器是不够的。

雪花算法的基本原理

请添加图片描述
  1. 第1位:
    二进制中最高位为1的是负数,而在随机ID中,只能为正数,故该位只能为0,无意义。

  2. 第2位~第42位:
    共41bit,是当前时间戳转换为二进制而来的。可以使用69年:year = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69

  3. 第43位~第52位:
    共10bit,是当前机器(服务器)的ID,其二进制数为210即1024,所以使用雪花算法的服务最多可以同时部署在1024台服务器上。需要注意的是这里10位中的5位是给机房的,5位是给机器(服务器)的,也就是一个雪花算法服务最多能部署在25个机房,每个机房最多有2^5个机器(服务器)。

  4. 第53位~第64位:
    共12bit,是毫秒内的序列号,即统一毫秒内生成的第几个ID,其二进制数为2^12即4096,所以同一雪花算法服务在同一毫秒内可生成4096个序列号ID,如果超出了,就只能等待下一毫秒再生成。

将以上四个部分拼接起来做位或运算,就组成了一个64位的全局唯一ID。

使用雪花算法生成ID

下载雪花算法的开源库

go get github.com/sony/sonyflake

生成ID

package main

import (
	"fmt"
	"github.com/sony/sonyflake"
	"time"
)

func main() {
	var setting sonyflake.Settings
	//设置起始时间
	startTime, err := time.Parse("2006-01-02 15:04:05", "2023-01-01 00:00:01")
	if err != nil {
		fmt.Println(err.Error())
	}
	setting.StartTime = startTime
	id := sonyflake.NewSonyflake(setting)

	userId, err := id.NextID()
	if err != nil {
		fmt.Println(err.Error())
	}
	fmt.Println(userId)
}

image-20230409112023241

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值