【golang】雪花算法的介绍和使用

snowflake

github地址:https://github.com/bwmarrin/snowflake

snowflake 是一个 Go 包,提供

  • 一个非常简单的推特雪花生成器。
  • 分析现有雪花 ID 的方法。
  • 将雪花 ID 转换为其他几种数据类型并返回的方法。
  • JSON 封送/取消封送函数,用于在 JSON API 中轻松使用雪花 ID。
  • 单调时钟计算可防止时钟漂移。

地位

这个包应该被认为是稳定和完整的。任何添加的内容 未来将强烈避免对现有函数进行 API 更改。

ID格式

默认情况下,ID 格式遵循原始的 Twitter 雪花格式。

整个 ID 是一个 63 位整数,存储在 int64 中
41 位用于使用自定义纪元以毫秒精度存储时间戳。
10 位用于存储节点 ID - 范围从 0 到 1023。
12 位用于存储序列号 - 范围从 0 到 4095。
自定义格式
您可以更改用于节点 ID 和步数(序列)的位数 通过设置雪花。节点位和雪花。步比特值。记住 这两者之间最多可以共享 22 位 值。您不必使用所有 22 位。

自定义纪元

默认情况下,此软件包使用 1288834974657 或 Nov 04 2010 01:42:54 的 Twitter 纪元。 您可以通过设置雪花来设置自己的纪元值。纪元到以毫秒为单位的时间 用作纪元。

自定义备注

设置自定义纪元或位值时,需要在调用之前设置它们 雪花包上的任何函数,包括 NewNode()。否则 您设置的自定义值将无法正确应用。

它是如何工作的

每次生成 ID 时,它都会像这样工作:

  • 毫秒精度的时间戳使用 41 位 ID 存储。
  • 然后将节点 ID 添加到后续位中。
  • 然后添加序列号,从 0 开始,并在同一毫秒内生成的每个 ID 递增。-如果您在序列滚动或溢出的同一毫秒内生成足够的 ID,则生成函数将暂停到下一毫秒。
    默认的推特格式如下所示。
+--------------------------------------------------------------------------+
| 1 Bit Unused | 41 Bit Timestamp |  10 Bit NodeID  |   12 Bit Sequence ID |
+--------------------------------------------------------------------------+

使用默认设置,这允许每个节点 ID 每毫秒生成 4096 个唯一 ID。

开始使用

  • 安装
    这假设你已经有一个有效的 Go 环境,如果没有,请先查看此页面。
go get github.com/bwmarrin/snowflake
  • 用法
    将包导入到项目中,然后使用 唯一的节点号。默认设置允许节点号范围从 0 到 1023。 如果您设置了自定义节点位值,则需要计算您的 节点编号范围将是。使用节点对象调用 Generate() 方法来 生成并返回唯一的雪花 ID。

请记住,您创建的每个节点都必须具有唯一的节点编号,即使 跨多个服务器。如果不保持节点号唯一,生成器 无法保证所有节点的唯一 ID。

  • 示例程序:
package main

import (
	"fmt"

	"github.com/bwmarrin/snowflake"
)

func main() {

	// Create a new Node with a Node number of 1
	node, err := snowflake.NewNode(1)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Generate a snowflake ID.
	id := node.Generate()

	// Print out the ID in a few different ways.
	fmt.Printf("Int64  ID: %d\n", id)
	fmt.Printf("String ID: %s\n", id)
	fmt.Printf("Base2  ID: %s\n", id.Base2())
	fmt.Printf("Base64 ID: %s\n", id.Base64())

	// Print out the ID's timestamp
	fmt.Printf("ID Time  : %d\n", id.Time())

	// Print out the ID's node number
	fmt.Printf("ID Node  : %d\n", id.Node())

	// Print out the ID's sequence number
	fmt.Printf("ID Step  : %d\n", id.Step())

  // Generate and print, all in one.
  fmt.Printf("ID       : %d\n", node.Generate().Int64())
}
Int64  ID: 1630021738207121408
String ID: 1630021738207121408
Base2  ID: 1011010011111000000000010001001111010000000000001000000000000
Base64 ID: MTYzMDAyMTczODIwNzEyMTQwOA==
ID Time  : 1677462441385
ID Node  : 1
ID Step  : 0
ID       : 1630021738207121409





在项目中使用

package snowflake

import (
	"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()
}

主程序中使用Init函数进行初始化

if err := snowflake.Init(settings.Conf.StartTime, settings.Conf.MachineID); err != nil {
	fmt.Printf("init sonwflake failed, err: %v\n", err)
	return
}

调用GenID()即可获得一个ID实例:

genID := GenID()
fmt.Printf("genID: %v\n", genID)

你可能感兴趣的:(golang,算法,开发语言)