雪花算法如何生成用户id?有什么高明之处?(代码片段)

了凡 了凡     2022-12-14     552

关键词:

博主简介

-- 本人 了 凡 ,意义是希望本人任何时候以善良为先,以人品为重,喜欢了凡四训中的立命之学、改过之法、积善之方、谦德之效四训。微信公众号【了凡银河系】期待你的关注。未来我们一起加油!

前言



雪花算法生成用户ID

分布式ID生成器

分布式ID的特点

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

snowflake算法介绍

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

设计思想

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

  2. 时间戳 占用41bit,单位为毫秒,总共可以容纳约69年的时间。当然,我们的时间毫秒计数不会真的从1970年开始记,那样我们的系统跑到 2039/9/7 23:47:35 就不能用了,所以这里的时间戳只是相对于某个时间的增量,比如我们的系统上线是2020-07-01,那么我们完全可以把这个timestamp当作是从 2020-07-01 00:00:00.000 的偏移量。

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

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

SnowFlake算法在同一毫秒内最多可以生成多少个全局唯一ID呢?
同一毫秒的ID数量=1024 X 4096= 4194304

snowflake的Go实现

Twitter

链接:https://github.com/bwmarrin/snowflake
github.com/bwmarrin/snowflake 是一个相当轻量化的snowflake的Go实现。

import (
   "fmt"
   _ "github.com/onsi/gomega"
   "time"

   sf "github.com/bwmarrin/snowflake"
)

var node *sf.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
   
   sf.Epoch = st.UnixNano() / 1000000
   node, err = sf.NewNode(machineID)
   return

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


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

索尼

链接:https://github.com/sony/snowflake
sonyflake是Sony公司的一个开源项目,基本思路和snowflake差不多,不过位分配上稍有不同:

这里的时间只用了39个bit,但时间的单位变成了10ms,所以理论上比41位表示的时间还要久(174年)。
Sequence ID 和之前的定义一致,Machine ID 其实就是节点id。sonyflake 库有以下配置参数:

type Settings struct 
   StartTime      time.Time
   MachineID      func() (uint16, error)
   CheckMachineID  func(uint16) bool

其中:

  • StartTime 选项和我们之前的 Epoch 差不多,如果不设置的话,默认是从 2014-09-0100 :00:00 +0000 UTC 开始。
  • MachineID 可以由用户自定义的函数,如果用户不定义的话,会默认将本机IP的低16位作为 machine id。
  • CheckMachineID 是由用户提供的检查 MachineID 是否冲突的函数。

使用示例:

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

var (
   sonyFlake     *sonyflake.Sonyflake
   sonyMachineID  uint16
)

func getMachineID() (uint16, error)  
   return sonyMachineID, nil


// 需传入当前的机器ID
func Init(startTime string, machineId uint16) (err error)  
   sonyMachineID = machineId
   var st time.Time
   st, err = time.Parse("2006-01-02", startTime)
   if err != nil 
      return err
   
   settings := sonyflake.Settings
      StartTime: st,
      MachineID: getMachineID,
   
   sonyFlake = sonyflake.NewSonyflake(settings)
   return



// GenID 生成id
func GenID() (id uint16, err error)  
   if sonyFlake == nil 
      err = fmt.Errorf("sony flake not inited")
      return
   
   id, err = sonyFlake.NextID()
   return


这次就先讲到这里,如果想要了解更多的golang语言内容一键三连后序每周持续更新!

雪花算法原理解析(代码片段)

...拆分,设置初始值和相同的自增步长。批量申请自增ID。雪花算法。百度UidGenerator算法(基于雪花算法实现自定义时间戳)。美团Leaf算法(依赖于数据库,ZK)。  本文主要介绍SnowFlake算法,是Twitter开源的分布式id生成算法。  其... 查看详情

springboot中使用雪花算法生成雪花id(代码片段)

目录1、什么是雪花算法2、雪花算法的优缺点3、springboot项目中使用雪花算法使用1、什么是雪花算法雪花算法(Snowflake)是一种生成全局唯一ID的算法,由Twitter公司开发。它可以在分布式系统中生成全局唯一的ID,... 查看详情

注意:雪花算法并不是id的唯一选择!(代码片段)

Hollis的新书限时折扣中,一本深入讲解Java基础的干货笔记!在《悟空传》篇外篇里,有一个忧伤的故事。秋天,树上掉下两片叶子,你要和它们说再见。但你如何知道这片叶子,不是另外一片叶子?是... 查看详情

mybatis-plus--使用雪花算法生成主键id--使用/分析(代码片段)

原文网址:MyBatis-Plus--使用雪花算法生成主键ID--使用/分析_IT利刃出鞘的博客-CSDN博客简介说明    本文介绍MyBatis-Plus如何使用其自带的雪花算法生成主键ID。MyBatis-Plus自带的雪花算法MyBatis-Plus自带雪花算法MyBatis-Plus默认使用... 查看详情

雪花算法生成的id在返回给前端之后和生成的不一样,到底是什么原因?(代码片段)

一、前言最近在做项目的时候发现用雪花算法生成的id传给前端以后跟生成的不一样,就纳闷,在想为什么会出现这样的问题?二、问题描述:雪花算法生成id为16位,返回到前端之后后两位变为0从两个点出发&... 查看详情

厉害了,美女同事用单例模式实现了雪花算法!(代码片段)

点击关注公众号,Java干货及时送达雪花算法雪花算法适用于生成全局唯一的编号,比如数据库主键id,订单编号等至于为什么叫雪花算法,是因为科学家通过研究认为自然界中不存在两片完全相同的雪花,所... 查看详情

分布式系统的唯一id如何生成(代码片段)

目录一、雪花算法的提前二、雪花算法的概述三、雪花算法的代码实现1、雪花算法代码2、测试代码一、雪花算法的提前针对业务数据来说,通常都是需要唯一id的,比如学生的学号、订单的订单号,支付流水的流水... 查看详情

分布式系统的唯一id如何生成(代码片段)

目录一、雪花算法的提前二、雪花算法的概述三、雪花算法的代码实现1、雪花算法代码2、测试代码一、雪花算法的提前针对业务数据来说,通常都是需要唯一id的,比如学生的学号、订单的订单号,支付流水的流水... 查看详情

雪花算法(代码片段)

...间戳、UUID都不是很可靠。为此,Twitter提出了一种名为“雪花算法”的算法来生成分布式全局唯一ID的算法算法介绍“雪花算法”生成的ID为\\(64\\)位整数,其中,前\\(41\\)位(\\(64\\)位整数第一位表示符号位,不作为开始位)表示... 查看详情

雪花算法生成id(代码片段)

packagecom.shopping.test;/***SnowFlake的结构如下(每部分用-分开):<br>*0-00000000000000000000000000000000000000000-00000-00000-000000000000<br>*1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正... 查看详情

雪花算法生成的id,前端无法使用(代码片段)

由于前端Number类型长度不够,所以雪花算法生成的ID,传递给前端就会精度丢失。解决方案:@ConfigurationpublicclassJacksonConfig@Bean@Primary@ConditionalOnMissingBean(ObjectMapper.class)publicObjectMapperja 查看详情

雪花算法:分布式唯一id生成利器(代码片段)

...的生成,都是软件开发人员经常会面临的一场景。而雪花算法便是这些场景的一个解决方案。以分布式ID为例,它的生成往往会在唯一性、递增性、高可用性、高性能等方面都有所要求。并且在业务处理时,还要防止... 查看详情

oracleid生成算法——雪花算法(代码片段)

背景近几日,被主键ID生成折磨的不太行,于是就在寻找一种合适的主键生成策略,选择一种合适的主键生成策略,可以大大降低主键ID的维护成本。主键ID生成方法最常用的4种主键ID生成方法UUID:全局唯一性&... 查看详情

oracleid生成算法——雪花算法(代码片段)

背景近几日,被主键ID生成折磨的不太行,于是就在寻找一种合适的主键生成策略,选择一种合适的主键生成策略,可以大大降低主键ID的维护成本。主键ID生成方法最常用的4种主键ID生成方法UUID:全局唯一性&... 查看详情

java实现雪花算法(snowflake)-生成永不重复的id(源代码+工具类)使用案例(代码片段)

雪花算法是由Twitter公司开源的snowflake(雪花)算法。1、雪花算法的原理雪花算法会生成一个64位的二进制数据,为一个Long型。(转换成字符串后长度最多19),其基本结构:第一位:为未使用第二部分:41位为毫秒级时间(41位... 查看详情

java实现雪花算法(snowflake)-生成永不重复的id(源代码+工具类)使用案例(代码片段)

雪花算法是由Twitter公司开源的snowflake(雪花)算法。1、雪花算法的原理雪花算法会生成一个64位的二进制数据,为一个Long型。(转换成字符串后长度最多19),其基本结构:第一位:为未使用第二部分:41位为毫秒级时间(41位... 查看详情

id生成器雪花算法和雪花算法的sony实现(代码片段)

1雪花算法首先确定我们的数值是64位,int64类型,被划分为四部分,不含开头的第一个bit,因为这个bit是符号位。用41位来表示收到请求时的时间戳,单位为毫秒,然后五位来表示数据中心的id,然后再五位来表示机器的实例id,... 查看详情

分布式全局唯一id解决方案(雪花算法)(代码片段)

...自增ID机制适合作分布式ID吗Redis集群实现分布式ID的利弊雪花算法(SonwFlake)使用糊涂工具包实现雪花算法优缺点:为什么需要分布式全局唯一ID以及分布式ID的业务需求在复杂分布式系统中,往往需要对大量的数据和消息进... 查看详情