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 雪花算法的资料请关注脚本之家其它相关文章!

相关文章

  • GO语言实现简单TCP服务的方法

    GO语言实现简单TCP服务的方法

    这篇文章主要介绍了GO语言实现简单TCP服务的方法,实例分析了Go语言实现TCP服务的技巧,需要的朋友可以参考下
    2015-03-03
  • Golang服务中context超时处理的方法详解

    Golang服务中context超时处理的方法详解

    在Go语言中,Context是一个非常重要的概念,它存在于一个完整的业务生命周期内,Context类型是一个接口类型,在实际应用中,我们可以使用Context包来传递请求的元数据,本文将给大家介绍Golang服务中context超时处理的方法和超时原因,需要的朋友可以参考下
    2023-05-05
  • go语言题解LeetCode453最小操作次数使数组元素相等

    go语言题解LeetCode453最小操作次数使数组元素相等

    这篇文章主要为大家介绍了go语言题解LeetCode453最小操作次数使数组元素相等示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 深入浅析Go中三个点(...)用法

    深入浅析Go中三个点(...)用法

    这篇文章主要介绍了深入浅析Go中三个点(...)用法,需要的朋友可以参考下
    2021-10-10
  • go build和go install的区别介绍

    go build和go install的区别介绍

    这篇文章主要介绍了go build和go install的区别介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go语言interface 与 nil 的比较

    Go语言interface 与 nil 的比较

    在golang中,nil只能赋值给指针、channel、func、interface、map或slice类型的变量。如果未遵循这个规则,则会引发panic。
    2017-08-08
  • Go语言学习技巧之命名规范

    Go语言学习技巧之命名规范

    最近在学习go语言,发现了不少需要整理的知识点,所以整理下分享出来,下面这篇文章主要给大家介绍了关于Go语言学习技巧之命名规范的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-12-12
  • 如何在Go语言中灵活运用匿名函数和闭包

    如何在Go语言中灵活运用匿名函数和闭包

    这篇文章主要为大家介绍了如何在Go语言中灵活运用匿名函数和闭包实现实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Go语言应该什么情况使用指针

    Go语言应该什么情况使用指针

    go语言的指针类型和C/C++的指针类型用法是一样的,那么Go语言应该什么情况使用指针,本文就详细的介绍一下,感兴趣的可以了解一下
    2021-07-07
  • go日志库中的logrus

    go日志库中的logrus

    这篇文章主要介绍了go日志库中的logrus主要包括go日志库logrus的安装和使用,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-08-08

最新评论