热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python教程分享Go实现分布式唯一ID的生成之雪花算法

分布式唯一id的生成背景:在分布式架构下,唯一序列号生成是我们在设计一个尤其是数据库使用分库分表的时候会常见的一个问题特性:全局唯一,这是基本要求,不能出现重复数字类型,趋势递增,

分布式唯一id的生成

背景:

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

特性:

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

雪花算法:

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

结果: long 型的id号(64位的id号)

核心思想(生成的id号是64位那么就对64位进行划分赋予特别的含义):

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

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

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

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

拓展:什么是时间戳?

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

优势:

//实现方法:  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=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

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

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

优点:

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

缺陷:

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

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

​ 可以分为两种情况:

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

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

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

​ 可以分为两种情况:

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

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

到此这篇关于go实现分布式唯一id的生成之雪花算法的文章就介绍到这了,更多相关go分布式唯一id 内容请搜索<编程笔记>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<编程笔记>!

需要了解更多python教程分享Go实现分布式唯一ID的生成之雪花算法,都可以关注python教程分享栏目&#8212;编程笔记


推荐阅读
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 本文讨论了在使用Git进行版本控制时,如何提供类似CVS中自动增加版本号的功能。作者介绍了Git中的其他版本表示方式,如git describe命令,并提供了使用这些表示方式来确定文件更新情况的示例。此外,文章还介绍了启用$Id:$功能的方法,并讨论了一些开发者在使用Git时的需求和使用场景。 ... [详细]
  • 起因由于我录制过一个小程序的课程,里面有消息模板的讲解。最近有几位同学反馈官方要取消消息模板,使用订阅消息。为了方便大家容易学 PythonFlask构建微信小程序订餐系统 课程。 ... [详细]
  • 本文介绍了Paxos的世界中关于复制日志与状态机的概念和重要性。通过存储日志来实现数据的持久化,并通过日志流来记录数据的变化,而不是直接持久化数据本身。这样做的好处是简化了持久化存储的操作,并且方便多机之间的数据同步。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • ElasticSerach初探第一篇认识ES+环境搭建+简单MySQL数据同步+SpringBoot整合ES
    一、认识ElasticSearch是一个基于Lucene的开源搜索引擎,通过简单的RESTfulAPI来隐藏Lucene的复杂性。全文搜索,分析系统&# ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
  • JVM:33 如何查看JVM的Full GC日志
    1.示例代码packagecom.webcode;publicclassDemo4{publicstaticvoidmain(String[]args){byte[]arr ... [详细]
  • 知识图谱表示概念:知识图谱是由一些相互连接的实体和他们的属性构成的。换句话说,知识图谱是由一条条知识组成,每条知识表示为一个SPO三元组(Subject-Predicate-Obj ... [详细]
  • 【回顾】聚焦DTCC | 巨杉数据库与您相约DTCC 数据库技术大会
    2018年5月10-12日,第九届中国数据库技术大会(DTCC2018)将以“数领先机•智赢未来”为主题,设定2大主会场及20个技术专场,邀请来自国内外互联网、金融、教育等行业百余 ... [详细]
  • 区块链为什么是不可篡改的
    不可篡改是区块链最为重要的特性和应用之一。其是由区块链本身的结构、共识机制、网络拓扑和加 ... [详细]
  • 什么是大数据lambda架构
    一、什么是Lambda架构Lambda架构由Storm的作者[NathanMarz]提出,根据维基百科的定义,Lambda架构的设计是为了在处理大规模数 ... [详细]
author-avatar
饥饿的饮水机
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有