分布式唯一ID的生成之雪花算法(Go实现)

Go实现雪花算法 Go实现雪花算法 一个简单的雪花算法的Go实现 需要的小伙伴直接拿去用就可以了。可以比较简单,一些数据你可以根据需要自定义就行了: 机器ID位数:没必要必须10位 开始时间戳:设置一个自己喜欢的,业务允许你只需要一天、一月的时间范围。42位也不是必须的。 序列所占位数,每msid范围,根据需要调整吧。 总得来说:除去第一个0是正负位不能变,其他63位,根据需要进行划分、组合,可以打进去很多信息,算法设计肯定很好,更多的希望你根据需要自我调整。 `` package main import ( "fmt 阅读详情
分布式唯一ID的生成

背景:

在分布式架构下,唯一序列号生成是我们在设计一个尤其是数据库使用分库分表的时候会常见的一个问题

特性:

  1. 全局唯一,这是基本要求,不能出现重复
  2. 数字类型,趋势递增,后面的ID必须比前面的大
  3. 长度短,能够提高查询效率,这也是从MySQL数据库规范出发的,尤其是ID作为主键时
  4. **信息安全,**如果ID连续生成,势必会泄露业务信息,所以需要无规则不规则
  5. 高可用低延时,ID生成快,能够扛住高并发,延时足够低不至于成为业务瓶颈.

雪花算法:

​ snowflake是推特开源的分布式ID生成算法

  1. 结果: long 型的ID号(64位的ID号)

  2. 核心思想(生成的ID号是64位那么就对64位进行划分赋予特别的含义):
    在这里插入图片描述

    41bit-时间戳决定了该算法生成ID号的可用年限.

    10bit-工作机器编号决定了该分布式系统的扩容性即机器数量.

    12bit-序列号决定了每毫秒单机系统可以生成的序列号

  3. 拓展:什么是时间戳?

    北京时间1970年01月01日08时00分00秒到此时时刻的总秒数

  4. 优势:

//实现方法:
package main


import (
	"errors"
	"fmt"
	"sync"
	"time"
)

/*
	雪花算法(snowFlake)的具体实现方案:
 */

type SnowFlake struct{
	mu sync.Mutex
	//雪花算法开启时的起始时间戳
	twepoch int64

	//每一部分占用的位数
	workerIdBits     int64 //每个数据中心的工作机器的编号位数
	datacenterIdBits int64 //数据中心的编号位数
	sequenceBits     int64 //每个工作机器每毫秒递增的位数

	//每一部分最大的数值
	maxWorkerId int64
	maxDatacenterId int64
	maxSequence int64

	//每一部分向左移动的位数
	workerIdShift int64
	datacenterIdShift int64
	timestampShift int64

	//当前数据中心ID号
	datacenterId int64
	//当前机器的ID号
	workerId int64
	//序列号
	sequence int64
	//上一次生成ID号前41位的毫秒时间戳
	lastTimestamp int64
}

/*
	获取毫秒的时间戳
 */
func (s *SnowFlake)timeGen()int64{
	return time.Now().UnixMilli()
}
/*
	获取比lastTimestamp大的当前毫秒时间戳
 */
func (s *SnowFlake)tilNextMills()int64{
	timeStampMill:=s.timeGen()
	for timeStampMill<=s.lastTimestamp{
		timeStampMill=s.timeGen()
	}
	return timeStampMill
}
func (s *SnowFlake)NextId()(int64,error){
	s.mu.Lock()
	defer s.mu.Unlock()
	nowTimestamp:=s.timeGen()//获取当前的毫秒级别的时间戳
	if nowTimestamp<s.lastTimestamp{
		//系统时钟倒退,倒退了s.lastTimestamp-nowTimestamp
		return -1,errors.New(fmt.Sprintf("clock moved backwards, Refusing to generate id for %d milliseconds",s.lastTimestamp-nowTimestamp))
	}
	if nowTimestamp==s.lastTimestamp{
		s.sequence=(s.sequence+1)&s.maxSequence
		if s.sequence==0{
			 //tilNextMills中有一个循环等候当前毫秒时间戳到达lastTimestamp的下一个毫秒时间戳
			nowTimestamp=s.tilNextMills()
		}
	}else{
		s.sequence=0
	}
	s.lastTimestamp=nowTimestamp
	return (nowTimestamp-s.twepoch)<<s.timestampShift| //时间戳差值部分
		s.datacenterId<<s.datacenterIdShift| //数据中心部分
		s.workerId<<s.workerIdShift| //工作机器编号部分
		s.sequence, //序列号部分
		nil
}

func NewSnowFlake(workerId int64,datacenterId int64)(*SnowFlake,error){
	mySnow:=new(SnowFlake)
	mySnow.twepoch=time.Now().Unix() //返回当前时间的时间戳(时间戳是指北京时间1970年01月01日8时0分0秒到此时时刻的总秒数)
	if workerId<0||datacenterId<0{
		return nil,errors.New("workerId or datacenterId must not lower than 0 ")
	}
	/*
		标准的雪花算法
	 */
	mySnow.workerIdBits =5
	mySnow.datacenterIdBits=5
	mySnow.sequenceBits=12

	mySnow.maxWorkerId=-1^(-1<<mySnow.workerIdBits)         //64位末尾workerIdBits位均设为1,其余设为0
	mySnow.maxDatacenterId=-1^(-1<<mySnow.datacenterIdBits) //64位末尾datacenterIdBits位均设为1,其余设为0
	mySnow.maxSequence=-1^(-1<<mySnow.sequenceBits)  //64位末尾sequenceBits位均设为1,其余设为0

	if workerId>=mySnow.maxWorkerId||datacenterId>=mySnow.maxDatacenterId{
		return nil,errors.New("workerId or datacenterId must not higher than max value ")
	}
	mySnow.workerIdShift=mySnow.sequenceBits
	mySnow.datacenterIdShift=mySnow.sequenceBits+mySnow.workerIdBits
	mySnow.timestampShift=mySnow.sequenceBits+mySnow.workerIdBits+mySnow.datacenterIdBits

	mySnow.lastTimestamp=-1
	mySnow.workerId=workerId
	mySnow.datacenterId=datacenterId

	return mySnow,nil
}



func main(){
	//模拟实验是生成并发400W个ID,所需要的时间
	mySnow,_:=NewSnowFlake(0,0)//生成雪花算法
	group:=sync.WaitGroup{}
	startTime:=time.Now()
	generateId:=func (s SnowFlake,requestNumber int){
		for i:=0;i<requestNumber;i++{
			s.NextId()
			group.Done()
		}
	}
	group.Add(4000000)
	//生成并发的数为4000000
	currentThreadNum:=400
	for i:=0;i<currentThreadNum;i++{
		generateId(*mySnow,10000)
	}
	group.Wait()
	fmt.Printf("time: %v\n",time.Now().Sub(startTime))
}

在这里插入图片描述

以上分析生成400WID号只需要803.1006ms(所以单机上可以每秒生成的ID数在400W以上)

优点:

  1. 毫秒数在高位,自增序列在低位,整个ID都是趋势递增
  2. 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成的ID性能也是非常高的
  3. 可以根据自身业务特性分配bit位,非常灵活

缺陷:

1. 依赖机器时钟,如果**机器时钟回拨**,会导致重复ID生成.
1. 在单机上是递增的,但是由于设计到分布式环境下,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况.

如何解决单机系统中时钟回拨问题:

​ 可以分为两种情况:

1. 如果**时间回拨时间较短,比如配置5ms以内**,那么可以直接等候一定的时间,让机器时间追上来
1. 如果**时间回拨时间较长**,我们不能接收这么长的阻塞等候,那么就有两个策略,直接拒绝,抛出异常;或者通过RD时钟回滚

布式环境下,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况.

如何解决单机系统中时钟回拨问题:

​ 可以分为两种情况:

1. 如果**时间回拨时间较短,比如配置5ms以内**,那么可以直接等候一定的时间,让机器时间追上来
1. 如果**时间回拨时间较长**,我们不能接收这么长的阻塞等候,那么就有两个策略,直接拒绝,抛出异常;或者通过RD时钟回滚

参考博客高并发情况下,雪花ID一秒400W个,以及分布式ID算法(详析)

分布式ID生成器及snowflake(雪花)算法实现 分布式ID的特点 全局唯一性:不能出现有重复的ID标识,这是基本要求。 递增性:确保生成ID对用户或业务都是递增的。 高可用性:确保任何时候都能生成正确的ID。 高性能性:在高并发的环境下依旧表现良好。 分布式ID生成器不仅仅用于生成用户ID,实际互联网中有很多场景都需要能够生成类似MYSQL自增ID这样不断增大,同时又不会重复的ID,以支持业务中的高并发场景。 比较经典的场景有:电商促销时短时间会有大量的订单涌入到系统,比如每秒10w+;微博热搜在短时间会产生大量的相关微博转发和评论信息。在这些业务环 阅读详情

相关推荐

唯一ID:雪花算法介绍与 Go 语言实现

snowflake 雪花算法可以在不依赖数据库的情况下,生成全局唯一的ID。

CodeSingerAlex的博客 3110

go实现雪花算法

雪花算法的go实现

qq_42170897的博客 1871

Go语言开发的分布式唯一ID生成系统后端

随着分布式系统的广泛应用,唯一ID的生成成为了系统设计中的一个重要问题。在分布式环境中,多个节点并发生成ID可能会导致ID冲突,因此需要一种可靠的机制来生成唯一ID。本文将介绍如何使用Go语言开发一个分布式唯一ID生成系统的后端,并提供相应的源代码。首先,我们需要确定唯一ID生成算法。雪花算法是Twitter开源的一种分布式ID生成算法,通过使用时间戳、机器ID和序列号来保证生成的ID的唯一性。例如,你可以将ID生成器封装为一个独立的服务,通过网络接口提供唯一ID的生成功能,以便其他系统可以远程调用。

OyLinux的博客 363

Go:雪花算法实现详解

符号位(1 bit):永远为0。时间戳(41 bits):记录时间戳,与生成时间有关。数据中心ID(5 bits):表示数据中心。机器ID(5 bits):表示机器或节点。序列号(12 bits):记录同一毫秒内的生成顺序。// 重新计算以防设置了自定义的NodeBits或StepBits// DEPRECATED: 以下代码块将在未来版本中移除。mu.Lock()// 添加time.Duration以确保使用单调时钟(如果可用)time int64node int64。

十年运维开发经验的王义杰在此分享自己的知识和经验 1267

5G 网络的移动性管理上下文对比介绍

5G 网络的移动性管理上下文对比介绍 4G/5G MM移动性管理机制对比 5G引入了新移动性管理状态,通过mobility pattern(移动方式)实现按需的移动性管理等。 MM的相关状态分为一下几种: RM状态(用户注册管理 注册态/非注册态)和CM状态(用户连接态/空闲态)独立;RM状态标识UE是否注册到网络,CM状态标识UE和核心网的信令连接是否存在。 RAN侧引入RRC-inactive state:UE(用户端)对于CN(核心网)而言处于连接态,对RAN(接入网)而言处于Ld..

m0_59032675的博客 4819

深入解析线性反馈移位寄存器(LFSR)的工作原理与实现

本文深入解析了线性反馈移位寄存器(LFSR)的核心原理与实现方法。通过生动的比喻和详细的步骤拆解,阐述了LFSR如何通过反馈多项式和移位操作生成伪随机序列,并对比了斐波那契型与伽罗瓦型两种硬件结构。文章还涵盖了LFSR在数字电路测试、通信扰码及快速伪随机数生成等关键应用场景,同时指出了其在密码学中的局限性,并提供了Python和C语言的高效实现代码示例。

weixin_29007243的博客 543

雪花算法 多少位_分布式ID生成方案:雪花算法(源自Twitter)

雪花(snowflake)在自然界中,是极具独特美丽,又变幻莫测的东西:雪花属于六方晶系,它具有四个结晶轴,其中三个辅轴在一个基面上,互相以60度的角度相交,第四轴(主晶轴)与三个辅轴所形成的基面垂直;雪花的基本形状是六角形,但是大自然中却几乎找不出两朵完全相同的雪花,每一个雪花都拥有自己的独有图案,就象地球上找不出两个完全相同的人一样。许多学者用显微镜观测过成千上万朵雪花,这些研究最后表明,形状...

weixin_39999859的博客 2948

2026华为OD机考新系统真题 + 双机位C卷 + 往年真题 - 题库目录分值说明 + 考点说明+在线OJ

2026年4月1日起,华为OD机试正式切换至新系统模式!采用力扣模式,无需自己写输入! 难度大幅度降低。正在备考华为OD机试的同学,优先刷新系统机试真题,可大幅提升通过率。 新系统考题考点与旧版一致,无需重新适应。本专栏所有算法题均配有详细思路解析,并提供C语言、JS、C++、Python、Go、Java多语言源码实现。订阅后私信即可开通专属OJ刷题权限,高效备考一次上岸!

算法大师! 45万+

雪花算法生成数字id_雪花算法生成唯一ID

能做啥?能够在分布式场景中为我们在每毫秒里面生成4096个纯数字的有序的唯一id,但只能连续使用69年(代码在69年后就不能保证生成的是唯一id了),并且你的分布式机器小于1024台。当然这里面出现的4096,69,1024都是可以通过参数配置调大调小的。golang版本实现image.png最高位是符号位,始终为0,不可用。41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一...

weixin_39954674的博客 1121

数字电路逻辑与设计实验一 门电路逻辑功能及测试

(1)选二输入四异或门电路 74LS86,按图 1-8 接线,输入端 1、2、4、5 接逻辑开 关(S1~S4),输出端 A、B、Y 接电平显示发光二极管.用六反相器(非门)按图 1-11 接线,输入 80KHz 连续脉冲,用双踪示波器测输入, 输出相位差,计算每个门的平均传输延迟时间的 tpd 值。测试不同的输入组合:对门电路进行全面的测试,尝试不同的输入组合,包括各种可能的逻辑状态。检查门电路的输入:确认门电路的输入是否正确,并且输入信号的电平符合门电路的规格要求。确保输入信号的稳定性和准确性。

欢迎交流学习心得 2万+

深入详解DICOM医学影像定位线相关知识:理解定位线的概念、定位线的作用以及定位线显示和计算原理

深入详解DICOM医学影像定位线相关知识:理解定位线的概念、定位线的作用以及定位线显示和计算原理

编程技术探索者,分享C/C++、C#、Java、数据库等开发经验,聚焦实战技巧与AI兴趣,助力编程爱好者成长。 2052

雪花算法简介以及代码实现

雪花算法学习笔记

D1842501760的博客 4581

泰凌微8258入门教程 基础篇①——Bluetooth® SIG Mesh 快速上手

Bluetooth® SIG Mesh Quick Start

6729

如何通过 go 语言实现雪花算法?

在 Go 语言中,可以通过实现雪花算法(Snowflake)来生成分布式唯一ID。雪花算法是 Twitter 提出的一种生成分布式唯一ID的算法,其核心思想是将一个64位的ID划分为多个部分,分别表示时间戳、机器ID和序列号。

Maisule的博客 157

ComfyUI 局部重绘工作流示例

本文介绍了使用ComfyUI进行图像局部重绘的基础工作流程,重点讲解如何修改人物眼睛颜色和表情。主要内容包括:1.准备工作(可选下载DreamShaperv8模型);2.加载素材图片和工作流文件;3.使用遮罩编辑器绘制需要修改的区域;4.修改提示词控制生成内容;5.调整denoise参数优化效果。教程提供了详细的提示词示例(如"smile,blackeyes"等)和参数设置建议,帮助用户通过多次尝试获得理想效果。该工作流适用于修改图像局部区域而不影响整体画面。

云域A的博客 331

对角两对双差速轮AGV的平移、直行、转弯和原地旋转之PID控制

本示例将展示如何使用PID控制算法,控制具有对角线布置的两对双差速轮(左前和右后)的AGV,实现平移、直行、转弯和原地旋转等运动。通过对车辆的运动学和PID控制器的设计,我们可以精确地控制AGV的运动

xiaoc100200的博客 1510

生成唯一字符串算法_分布式唯一ID生成方案之雪花算法

通常我们在涉及到数据分库分表后需要有一个唯一ID来标识一条数据。例如在做金融系统的订单、运营活动的优惠券、社区的问答服务,我们都需要一个能够生成全局唯一ID的服务,而这个全局唯一的ID就叫分布式ID。那么分布式ID需满足如下条件。全局唯一:需要保证分布式ID是全局性唯一的。易于接入:系统设计和实现上要尽可能的简单易于维护。趋势递增:最好具有趋势递增特性。高性能:高可用并且低延时,ID生成...

weixin_39930711的博客 668

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Go 雪花算法生成ID

配置文件读取结构体

baidu_41388533的博客 1063

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

gin-vue-admin二开使用雪花算法生成唯一标识 id

雪花算法,由Twitter开源,是一种分布式唯一ID生成算法。这种算法的主要特点是简单、高效,生成的64位整数ID全局唯一,且趋势递增。在单机上,雪花算法生成的ID也能保持递增特性,但在不同的机器上,由于各自有不同的时间戳,因此生成的ID不会冲突。这种算法的性能相当高,每秒中能生成数百万的自增ID。因此,雪花算法被广泛应用于分布式系统中需要唯一ID的场景。例如,美团开源的分布式ID生成器Leaf也采用了雪花算法来保证全局唯一和趋势递增。

weixin_47024018的博客 1174

雪花算法及其golang实现

什么是雪花算法 雪花算法的含义及用途 分布式结构中,常要求服务器集群内保持唯一id。如果在单个机器上实现唯一id,非常简单。但是在高并发集群中实现,则可能会出现id冲突的问题。雪花算法(SnowFlake)就是解决这一问题的。 算法思想 雪花算法是Twitter开源的分布式唯一id生成算法。它的核心思想就是用一个64bit的长整型作为唯一id,长整型中包含毫秒级时间戳,机器编号,机器内序号。 唯一id的组成 64个bit中,第一位的bit是不使用的。因为id的类型是长整型,如果第一位为1,则值为复数。所以第

qq_34905113的博客 642

【Skynet 入门实战练习】分布式 ID | 雪花算法 | 缓存设计 | LRU算法 | 数据库

本章实现了雪花算法生成ID系统,自定义了项目的缓存模块,使用了 MongoDB 数据库存储游戏数据

Cauchy的博客 1957

分布式ID之雪花算法

通俗易懂的分布式ID之雪花算法!说人话的!没有那么多绕绕弯弯的!

niuzai_的博客 189

goframe框架签到系统项目开发(分布式 ID 生成器、雪花算法、抽离业务逻辑到service层)

本文介绍了分布式ID生成系统的关键技术与实现方案。主要内容包括:1)注册、登录和用户认证流程设计;2)分布式ID的特点(全局唯一、递增、高可用、高性能)及其在电商、社交等场景的应用;3)对比数据库自增ID和UUID的局限性;4)详细解析Twitter的Snowflake算法结构及其Go语言实现(bwmarrin/snowflake和sony/sonyflake两个库);5)给出了在用户注册流程中集成雪花ID生成器的具体代码示例。重点阐述了如何通过64位ID结构(时间戳+节点ID+序列号)满足分布式系统对唯一

Atticus的博客 1097

12.2go小项目-实现雪花算法

雪花算法(Snowflake Algorithm)是Twitter开源的一种分布式ID生成算法,它可以生成全局唯一且有序的64位ID。

chxii的专栏 966

go的雪花算法代码分享

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

weixin_42127508的博客 329

(11)go-micro微服务雪花算法

雪花算法是推特开源的分布式ID生成算法,用于在不同的机器上生成唯一的ID的算法。该算法生成一个64bit的数字作为分布式ID,保证这个ID自增并且全局唯一。1.第一位占用1bit,其值始终是0,没有实际作用。2.时间戳占用41bit,单位为毫秒,总共可以容纳约69年的时间。当然,我们的时间毫秒计数不会真的从1970年开始记,那样我们的系统跑到2039/9/7 23:47:35 就不能用了,所以这里的时间戳只是相对。

夏沫の梦的博客 718
上一篇: FabricV2.2测试网络搭建以及开发环境部署
下一篇: FabricV2.2中使用的密码学算法和国密算法对应关系
Blockchain410
博客等级 码龄5年 3230粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blockchain410

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值