分布式ID生成--snowflake算法

目录

分布式ID的特点

  • 全局唯一性:不能出现有重复的ID标识,这是基本要求。
  • 递增性:确保生成的ID对于用户或业务是递增的。
  • 高可用性:确保任何时候都能生成正确的ID。
  • 高性能性:在高并发的环境下依然表现良好。

原理

雪花算法,是Twitter开源的由64位整数组成分布式ID,性能较高,并且在单机上递增

1.第一位 占用1bit,其值始终是0,没有实际作用。

2.时间戳 占用41bit,单位为毫秒,总共可以容纳约69年的时间。当然,我们的时间毫秒计数不会真的从1970年开始记,所以这里的时间戳只是相对于某个时间的增量。

3.工作机器id 占用10bit,其中高位5bit是数据中心ID,低位5bit是工作节点ID,最多可以容纳1024个节点。

4.序列号 占用12bit,用来记录同毫秒内产生的不同id。每个节点每毫秒0开始不断累加,最多可以累加到4095,同一毫秒一共可以产生4096个ID

同一毫秒的ID数量 = 1024 * 4096 = 4194304

算法实现

go 复制代码
package main

import (
	"fmt"
	"github.com/bwmarrin/snowflake"
	"time"
)

var node *snowflake.Node

func Init(startTime string, machineID int64) (err error) {
	var st time.Time
	st, err = time.Parse("2006-01-02", startTime)
	if err != nil {
		return
	}
	snowflake.Epoch = st.UnixNano() / 1000000
	node, err = snowflake.NewNode(machineID)
	return
}

func GenID() int64 {
	return node.Generate().Int64()
}

func main() {
	if err := Init("2020-07-01", 1); err != nil {
		fmt.Printf("init failed, err:%v\n", err)
		return
	}
	id := GenID()
	fmt.Println(id)
}

使用场景

不仅仅是用于用户ID,实际上互联网中有很多场景需要能够生成类似MySQL自增ID这样不断增大,同时又不会重复的id,以支持业务中的高并发场景,例如在消息队列系统中,为每一个消息生成全局的唯一ID等。

比较典型的场景有:电商促销时短时间内会有大量的订单涌入到系统,微博出现爆炸性新闻时会产生大量的相关微博转发和评论消息。

优缺点

优点

  • 唯一性:雪花算法生成的ID在分布式系统中是唯一的。这是因为它结合了时间戳、机器ID和序列号,确保在相同的时间戳内、相同的机器ID下生成的ID是唯一的。
  • 有序性:生成的ID是递增的(在同一毫秒内),这有助于提高数据库索引性能,减少数据库的碎片化。
  • 高性能:雪花算法是一种轻量级的算法,计算简单快速,生成ID的速度很高。
  • 分布式可用性:适用于分布式系统,不同节点上生成的ID可以保持全局唯一性。

缺点

  • 依赖时钟:雪花算法的唯一性基于时间戳,因此如果系统时间发生回退(例如,时钟同步问题、时钟漂移等),可能会导致生成的ID不唯一,甚至出现ID倒序的情况。
  • 机器ID有限制:机器ID的位数限制了系统所能容纳的节点数目,一般情况下,最多支持4096个节点。

注意事项

js支持最大的整型范围为53位,超过这个范围就会丢失精度,53之内可以直接由js读取,超过53位就需要转换成字符串才能保证js处理正确。53位存储的话,32位存储秒级时间戳,5位存储机器码,16位存储序列化,这样每台机器每秒可以生产65536个不重复的id。

相关推荐
茶杯梦轩1 天前
从零起步学习RabbitMQ || 第三章:RabbitMQ的生产者、Broker、消费者如何保证消息不丢失(可靠性)详解
分布式·后端·面试
回家路上绕了弯3 天前
深入解析Agent Subagent架构:原理、协同逻辑与实战落地指南
分布式·后端
初次攀爬者8 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
花酒锄作田9 天前
Gin 框架中的规范响应格式设计与实现
golang·gin
断手当码农9 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
qwfys2009 天前
How to install golang 1.26.0 to Ubuntu 24.04
ubuntu·golang·install
初次攀爬者9 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端
业精于勤_荒于稀9 天前
物流订单系统99.99%可用性全链路容灾体系落地操作手册
分布式
Asher05099 天前
Hadoop核心技术与实战指南
大数据·hadoop·分布式
codeejun9 天前
每日一Go-25、Go语言进阶:深入并发模式1
开发语言·后端·golang