分布式唯一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

[原创]Keil工程STM32F103C8T6无缝转换到STM32F103RCT6

有个项目,老版本是STM32F103C8T6,硬件资源不够了,新版本采用STM32F103RCT6。 无缝过渡,如下: 选定芯片 宏定义改为STM32F10X_HD,USE_STDPERIPH_DRIVER 删除原有的启动汇编文件,更换为高密度器件汇编文件 时钟系统紊乱? 那得看你程序怎么写: 先看F103时钟树 int main(void) { unsigned char stat...

江东风又起 2万+

WSL2+Docker实战:在Windows上部署MinerU 2.5.3,解锁媲美Demo的VLM PDF解析能力

本文详细介绍了如何在Windows系统上通过WSL2+Docker部署MinerU 2.5.3,实现媲美Demo的VLM PDF解析能力。文章涵盖环境准备、Docker部署实战技巧及高级使用技巧,特别针对PDF识别中的复杂排版、公式和图表处理提供了优化方案,帮助用户高效处理学术论文和技术文档。

weixin_29291573的博客 482

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

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

weixin_39999859的博客 2948

历年北京理工大学复试专业综合题

。

A place to record sth. 2万+

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

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

weixin_39954674的博客 1121

【Bug已解决】claude: No such file or directory — Claude Code 命令凭空消失解决方案

方案适用场景推荐指数难度方案一:重建软链接所有平台,软链接断裂⭐⭐⭐⭐⭐低方案二:修复 shebangnvm 用户,不想重装⭐⭐⭐⭐中方案三:nvm default aliasnvm 用户,长期稳定⭐⭐⭐⭐低方案四:切换到 Volta频繁切换 Node.js 版本⭐⭐⭐中方案五:修复 PATHPATH 配置丢失⭐⭐⭐⭐低方案六:Homebrew 安装macOS 用户,npm 不稳定⭐⭐⭐⭐低根本原因与。

博客 1万+

ENVI预处理GF-1号WFV1遥感数据提取NDVI指数

使用ENVI处理GF-1号遥感数据提取NDVI指数

所有专家都曾始于新手 8177

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

雪花算法学习笔记

D1842501760的博客 4581

基于Python的Booking酒店数据爬虫实战:最新技术与完整代码解析

本文将详细介绍如何使用Python构建一个高效的Booking酒店数据爬虫,涵盖从基础爬取到高级反反爬技术的完整实现。我们将使用最新的Python爬虫技术栈,包括requests-html、Playwright、智能代理轮换等技术,并提供完整的可运行代码示例。文章将深入探讨爬虫的各个组成部分,包括数据提取、存储、反反爬策略以及性能优化等方面。关键词:Python爬虫、Booking数据采集、反反爬技术、Playwright、数据存储。

2201_76125261的博客 936

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

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

Maisule的博客 157

【读代码】SQLBot:开源自然语言转SQL智能助手原理与实践

SQLBot是 DataEase 团队开源的自然语言转 SQL 智能助手,致力于让非技术用户也能通过自然语言与数据库对话,自动生成 SQL 查询,实现自助数据分析、智能BI问答、报表生成等场景。SQLBot 结合了大语言模型(LLM)、数据库元数据解析、SQL解析与执行等多项技术,具备强大的多数据库适配能力和灵活的扩展性。降低数据分析门槛,让业务人员无需掌握SQL即可获取数据洞察支持多种数据库类型,适应企业多样化数据环境提供可扩展的API和插件机制,便于集成到各类BI、数据平台和业务系统。

kakaZhui的博客 829

SecOC专题之新鲜值TripCnt

本系列为一步步拆解新鲜值的分发及管理而撰写文章属于原创,根据自身开发经验及理解撰写,若有错误请指出Trip Counter是新鲜值中变化最慢的一个part,并且自增到最大值时,会从头开始翻转计数。Trip Counter需要收发双方都保存,由于其变化较慢,所以不会经常进行同步该值。这就要求开发过程中保证每次对该值的读写必须要正确。

qq_22969363的博客 1154

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

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

weixin_39930711的博客 668

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Go 雪花算法生成ID

配置文件读取结构体

baidu_41388533的博客 1063

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

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

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

weixin_47024018的博客 1174

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

雪花算法及其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、付费专栏及课程。

余额充值