Go雪花算法的作用领域及实现方法示例

 更新时间:2023年10月24日 11:52:18   作者:枫潇潇兮  
这篇文章主要为大家介绍了Go雪花算法的作用领域及实现方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

什么是雪花算法

雪花算法(Snowflake)是Twitter开源的一种分布式系统唯一ID生成策略,其核心思想是利用41位作为毫秒数,5位作为数据中心的ID,5位作为机器ID,12位作为毫秒内的序列号,这样可以保证每毫秒内可以产生多达4096个ID,整个结构如下:1位标识位 + 时间戳41位 + 数据中心5位 + 机器5位 + 序列号12位。这种算法可以保证全局唯一性。

雪花算法的作用领域

雪花算法主要用于分布式系统或大型并发系统中,为了解决全局唯一标识符(ID)的生成问题。这些领域包括但不限于:

  • 订单号生成系统
  • 数据库的主键生成
  • 分布式缓存中的key生成
  • 分布式系统中数据的唯一性确认
  • 在大型互联网或者中型软件系统中,生成全局唯一ID的场景等。

Go如何实现雪花算法

方式一:引入三方库

 引入包

go get -u github.com/bwmarrin/snowflake

 实现代码

package main
import (
  "fmt"
  "github.com/bwmarrin/snowflake"
)
func main() {
  node, err := snowflake.NewNode(1)
  if err != nil {
    fmt.Println(err)
    return
  }
  id := node.Generate()
  fmt.Println(id)
}

这个例子先创建了一个snowflake节点,然后生成一个ID。

注意:这个库所用的雪花算法有些许与原始算法对位宽的分配有所不同,Twitter版本是 1位标识 + 时间戳41位 + 数据中心5位 + 机器5位 + 序列号12位。而bwmarrin库版本是 snowflake.NodeBits=10,snowflake.StepBits=12,即数据中心和机器ID共占10位,序列号占12位。

方式二:实现源码

package main
import (
  "fmt"
  "sync"
  "time"
)
const (
  epoch     int64 = 1526285084378           // 设置起始时间(这里一般是项目上线时间)
  timestampBits = uint(41)                  // 时间戳占41位
  machineBits   = uint(5)                   // 机器位占5位
  sequenceBits  = uint(12)                  // 序列号占12位
  machineMax    = int64(-1) ^ (int64(-1) << machineBits)  // 机器标识最大值
  sequenceMask  = int64(-1) ^ (int64(-1) << sequenceBits) // 序列号最大值
  machineShift  = sequenceBits              // 机器码左移位数
  timestampShift = machineBits + sequenceBits // 时间戳左移位数
)
var (
  machineID  int64
  sequence   int64
  lastTimestamp int64
  lock sync.Mutex
)
func NextID() int64 {
  lock.Lock()
  defer lock.Unlock()
  timestamp := time.Now().UnixNano() / int64(time.Millisecond)
  if timestamp < lastTimestamp {
    panic("invalid timestamp")
  }
  if timestamp == lastTimestamp {
    sequence = (sequence + 1) & sequenceMask
    if sequence == 0 {
      timestamp = waitNextMillisecond(lastTimestamp)
    }
  } else {
    sequence = 0
  }
  lastTimestamp = timestamp
  return ((timestamp - epoch) << timestampShift) | (machineID << machineShift) | sequence
}
func waitNextMillisecond(last int64) int64 {
  timestamp := time.Now().UnixNano() / int64(time.Millisecond)
  for timestamp <= last {
    timestamp = time.Now().UnixNano() / int64(time.Millisecond)
  }
  return timestamp
}
func main() {
  fmt.Println(NextID())
}

注意,这只是一个简化版的雪花算法。在生产环境中,你需要处理乱序和时钟回拨问题,以及考虑数据中心和机器标识的生成问题。此外,epoch时间需要你自己设定,一般设置为系统上线的时间。

以上就是Go雪花算法的作用领域及实现方法示例的详细内容,更多关于Go 雪花算法的资料请关注脚本之家其它相关文章!

相关文章

  • golang 删除切片的某个元素及剔除切片内的零值方式

    golang 删除切片的某个元素及剔除切片内的零值方式

    这篇文章主要介绍了golang 删除切片的某个元素及剔除切片内的零值方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • 浅析Go语言中的缓冲区及其在fmt包中的应用

    浅析Go语言中的缓冲区及其在fmt包中的应用

    这篇文章主要为大家详细介绍了Go语言中的缓冲区及其在fmt包中的应用的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2024-01-01
  • go常用指令之go mod详解

    go常用指令之go mod详解

    当go命令运行时,它查找当前目录然后查找相继的父目录来找出 go.mod,下面这篇文章主要给大家介绍了关于go常用指令之go mod的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • go语言规范RESTful API业务错误处理

    go语言规范RESTful API业务错误处理

    这篇文章主要为大家介绍了go语言规范RESTful API业务错误处理方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Go语言入门13之runtime包案例讲解

    Go语言入门13之runtime包案例讲解

    这篇文章主要介绍了Go语言入门runtime包相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • GO语言ini配置文件的读取的操作

    GO语言ini配置文件的读取的操作

    这篇文章主要介绍了GO语言ini配置文件的读取的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • GPT回答:go语言和C语言切片对比

    GPT回答:go语言和C语言切片对比

    这篇文章主要为大家介绍了GPT回答:go语言和C语言切片对比,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • 深入理解Golang中的dig包管理和解决依赖关系

    深入理解Golang中的dig包管理和解决依赖关系

    这篇文章主要为大家详细介绍了golang中dig包的使用方法,探讨其应用场景,并提供一些示例,展示如何结合其他库来更好地实现这些场景,感兴趣的小伙伴可以了解下
    2024-01-01
  • go语言 xorm框架 postgresql 的用法及详细注解

    go语言 xorm框架 postgresql 的用法及详细注解

    这篇文章主要介绍了go语言 xorm框架 postgresql 的用法及详细注解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Golang中sync.Mutex的源码分析

    Golang中sync.Mutex的源码分析

    这篇文章将带大家从源码分析一下Golang中sync.Mutex的使用,文中的示例代码讲解详细,对我们学习Golang有一定的帮助,需要的可以参考一下
    2023-03-03

最新评论