snowflake

package
v0.3.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2021 License: MIT Imports: 6 Imported by: 1

README

雪花算法

参考了https://github.com/bwmarrin/snowflake的雪花算法实现,此算法是标准的twitter雪花算法。 此仓库作者可能想将一些雪花算法的meta信息存放在Node结构体中,但当Node产生出ID后, 从ID本身其实并不能倒推原来雪花算法中的各个字段的meta信息,其本质问题是ID本身就是64位整数, 能存储的信息实在有限,如果需要将一些算法相关的信息存放在ID中,本身又会缩短ID生成的有效信息范围。 按照现有算法,在每个节点上每毫秒可以产生4096个ID,总共可以切分1024个节点,如果在ID中带上节点/步长相关的信息, 那要么会让切分节点数量变少,要么让每毫秒产生的ID数变少,总之都会让产生ID的效率变低。

主要的改动

  • 去掉了原来仓库中一些不那么常用的函数
  • 对雪花算法增加了一定程度的配置灵活度:
    1. 雪花算法中的创世时间可以配置,举例来说,如果在2022年启动一个项目,可以把创世时间设为2022年, 这样会让雪花算法ID的生命周期更长。
    2. 雪花算法中节点数量可以配置成支持1024/512/256个节点的三种节点模式,标准是支持1024个节点, 如果不需要那么多节点,可以配置成512和256个节点,这样的好处是将节约下来的bit供毫秒时间戳使用, 让ID的生命周期更长久。
    3. 标准雪花算法中,步长放置在最低位,节点信息居中。这里增加了配置选项,可以让节点信息放置在最低位,步长信息居中。
    4. 添加了一对函数,CnStyle/FromChStyle,这对函数可能在中国式系统开发中有用。这两个函数主要功能是, CnStyle会将雪花算法产生的ID转换成YYYYMMDDHHMMSSMMMXXXXXXX这样总长度为24的形式, YYYY(年,4位)MM(月,2位)DD(日,2位)HH(小时,2位)MM(分,2位)SS(秒,2位)MMM(毫秒,3位)XXXXXXX(节点和步长组成的整数,7位), 每个字段都会在位数不够的情况下,补足高位的0,如果举例来说,如果月份为5,则会补为05。 FromChStyle则会将这样带日期信息的字符串转化成ID本身。

特别注意:关于雪花算法配置函数Setup

缺省配置能应付绝大多数场景,如果在某种情况下,需要修改雪花算法配置,这些配置项主要是:

  1. 节点的位数可以配置为10/9/8,即分别支持1024/512/256个节点,节点少则意味着ID的生命周期更长。比如1024个节点,ID可用69年,512个节点则可以 让ID可用138年。
  2. 节点信息可以放置在最低位,此时步长信息会居中。

如果在某种场景下修改了雪花算法的配置,务必需要记住的是,与此相关的场景都需要使用此配置。因为雪花算法中,节点位数与其放置的位置都不会存在ID中, 换句话说,相关的代码实际上就是雪花算法配置的元信息,一旦投入了某种配置,就不要再修改它了。

雪花算法的回退问题

以前我写了一篇《时间同步次生问题与定时器》的文章,其中支持雪花算法可能产生单调不递增的ID,在时间回退的情况下。现在看来当时我的结论是错误的, 相关的代码已经清楚表明,雪花算法中时间的计算用的是单调时间计算。

    //在NewNode时使用了单调时间
    var curTime = time.Now()
    // add time.Duration to curTime to make sure we use the monotonic clock if available
    n.epoch = curTime.Add(time.Unix(_epoch/SDivMs, (_epoch%SDivMs)*MsDivNs).Sub(curTime))
    //在生成ID时同样使用了单调时间计算,而不是简单粗暴把时间戳进行加减运算
    var now = time.Since(n.epoch).Nanoseconds() / MsDivNs

Documentation

Index

Constants

View Source
const (
	//StepBits 步长永远设置为12 bits
	StepBits uint8 = 12

	Node1024 NodeBitsMode = 10
	Node512  NodeBitsMode = 9
	Node256  NodeBitsMode = 8

	//SDivMs 1 second = 1000 ms
	SDivMs = 1000
	//MsDivNs 1 ms = 1000000 ns
	MsDivNs = 1000000

	//TimeStrLen convert id to time style string, its length is fixed 24
	TimeStrLen = 24
)

Variables

This section is empty.

Functions

func CnStyle added in v0.2.5

func CnStyle(id int64) string

CnStyle A weird implement for chinese style 总共长度24 17位时间- 20210901 003859 000 7位NODE+STEP

func FromChStyle added in v0.2.5

func FromChStyle(v string) (int64, error)

FromChStyle from string to int64

func IDParse added in v0.2.5

func IDParse(id int64) (timeMs, node, step int64)

IDParse figure out time/node/step from id Return : ms timestamp, node, step

func IDParseEx added in v0.2.5

func IDParseEx(id int64) (t time.Time, node, step int64)

IDParseEx figure out time/node/step from id Return : time.Time, node, step

func Setup added in v0.2.5

func Setup(opts ...Option)

Setup setup snowflake

func TimeBetweenID added in v0.3.4

func TimeBetweenID(begin time.Time, end time.Time) (min, max int64)

TimeBetweenID figure out a specific [after time, before time] The calculation is based on second

func TimeIDRange added in v0.3.4

func TimeIDRange(t time.Time) (min, max int64)

TimeIDRange figure out a specific time min and max id The calculation is based on second

Types

type Node

type Node struct {
	// contains filtered or unexported fields
}

A Node struct holds the basic information needed for a snowflake generator node

func NewNode

func NewNode(node int64) (*Node, error)

NewNode returns a new snowflake node that can be used to generate snowflake

func (*Node) Generate

func (n *Node) Generate() int64

Generate creates and returns a unique snowflake ID To help guarantee uniqueness - Make sure your system is keeping accurate system time - Make sure you never have multiple nodes running with the same node ID

type NodeBitsMode added in v0.2.5

type NodeBitsMode uint8

type Option added in v0.2.5

type Option func(o *_Option)

func NodeAtLowest added in v0.2.5

func NodeAtLowest() Option

NodeAtLowest : 设置节点位数模式

func UseEpoch added in v0.2.5

func UseEpoch(t time.Time) Option

UseEpoch : 设置创世时间

func UseNodeMode added in v0.2.5

func UseNodeMode(m NodeBitsMode) Option

UseNodeMode : 设置节点位数模式

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL