idgen

package
v1.0.8 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2024 License: BSD-3-Clause Imports: 12 Imported by: 0

README

uuid

分布式ID生成

Usage

雪花算法
时间戳 WorkerID SeqID
  • 把一个64位的整数分成3个区间,分别用于时间戳workerIDseqID
  • 时间戳代表时间单元需要一直递增,不同的时间单元实现有毫秒、秒、厘秒等,这里依赖时钟不回调;
  • workerID用来标识分布式环境下的每个service;
  • seqID在一个时间单元内持续自增,如果在单个时间单元内seqID溢出了,需要sleep等待进入下一个时间单元;

分布式部署下雪花ID只保证了唯一性,无法保证顺序性(递增), 因为ID的分段包含了服务ID,在同个时间单元内(10ms)服务A按时钟后生成的ID会小于服务B按时钟先生成的ID。

不同的雪花算法的参考实现。

  • sony的实现 https://github.com/sony/sonyflake
  • 百度的实现 https://github.com/baidu/uid-generator
  • 美团的实现 https://github.com/Meituan-Dianping/Leaf
发号器算法
  • 算法把一个64位的整数按step划分为N个号段;
  • 每个service向发号器申请领取一个代表号段的counter;
  • service内部使用这个号段向业务层分配ID;
  • service重启或者号段分配完,向发号器申请下一个号段;
  • 要求底层存储不能随意被修改影响到上层算法分配;

发号器依赖存储组件,对存储组件的需求是能实现整数自增。

发号器ID只保证了唯一性,无法保证顺序性(递增),因为多个服务同时生成, 如果服务1的生成速度如果比服务2快,服务1的ID号段会先用完, 那么服务1上按时钟先分配的ID会大于服务2上按时钟后分配的ID。

本包提供多种存储选择,redis和mongodb

Documentation

Index

Constants

View Source
const (
	SequenceBits       = 12
	WorkerIDBits       = 13
	TimeUnitBits       = 36
	ClockBackwardsBits = 2
	WorkIDMask         = 1<<WorkerIDBits - 1
	MaxSeqID           = (1 << SequenceBits) - 1
	TimestampShift     = WorkerIDBits + SequenceBits
	MaxTimeUnits       = (1 << TimeUnitBits) - 1
	BackwardsMaskShift = TimeUnitBits + WorkerIDBits + SequenceBits

	TimeUnit    = int64(time.Millisecond * 10)    // 厘秒(10毫秒)
	CustomEpoch = int64(1704038400 * time.Second) // 起始纪元 2024-01-01 00:00:00 UTC
)

一个64位UUID由以下部分组成

1位符号位
2位时钟回拨标记,时钟最多被回拨3次
36位时间戳(厘秒),~=21y288d, 最大可以表示到2045-10-10
13位服务器ID,最大服务器ID=8191
12位序列号,单个时间单位的最大分配数量(409/毫秒)
View Source
const (
	CollectionName = "uuid"
)
View Source
const (
	DefaultSeqIDStep = 2000 // 默认步长
)

Variables

View Source
var (
	ErrClockGoneBackwards = errors.New("clock gone backwards")
	ErrTimeUnitOverflow   = errors.New("clock time unit overflow")
	ErrUUIDIntOverflow    = errors.New("uuid integer overflow")
)
View Source
var ErrCounterOutOfRange = errors.New("counter out of range")

Functions

This section is empty.

Types

type Counter

type Counter struct {
	Label string `bson:"label"`   // 识别符
	Value int64  `bson:"counter"` // 计数器
}

Counter 计数器

type CounterStore

type CounterStore interface {
	Init(context.Context) error
	Close() error
	Incr(context.Context) (int64, error)
}

CounterStore 表示一个存储组件,维持一个持续递增(不一定连续)的counter

func NewMongoDBCounter

func NewMongoDBCounter(uri, db, label string) CounterStore

func NewRedisCounter

func NewRedisCounter(addr, key string) CounterStore

type IDGenerator

type IDGenerator interface {
	Next(context.Context) (int64, error)
}

IDGenerator ID生成器

type MongoDBCounter

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

MongoDBCounter 使用MongoDB的自增计数器

func (*MongoDBCounter) Close

func (s *MongoDBCounter) Close() error

func (*MongoDBCounter) Incr

func (s *MongoDBCounter) Incr(ctx context.Context) (int64, error)

func (*MongoDBCounter) IncrementAndLoad added in v1.0.3

func (s *MongoDBCounter) IncrementAndLoad(ctx context.Context, n int, ctr *Counter) error

IncrementAndLoad 把counter自增再读取最新的counter https://docs.mongodb.com/manual/core/write-operations-atomicity/

func (*MongoDBCounter) Init

func (s *MongoDBCounter) Init(ctx context.Context) error

type RedisCounter

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

RedisCounter 基于redis INCR命令实现的计数器

func (*RedisCounter) Close

func (s *RedisCounter) Close() error

func (*RedisCounter) Incr

func (s *RedisCounter) Incr(ctx context.Context) (int64, error)

func (*RedisCounter) Init

func (s *RedisCounter) Init(ctx context.Context) error

type SegmentIDGen

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

func NewSegmentIDGen

func NewSegmentIDGen(store CounterStore, step int32) *SegmentIDGen

func (*SegmentIDGen) Init

func (g *SegmentIDGen) Init(ctx context.Context) error

func (*SegmentIDGen) MustNext

func (g *SegmentIDGen) MustNext(ctx context.Context) int64

func (*SegmentIDGen) Next

func (g *SegmentIDGen) Next(ctx context.Context) (int64, error)

Next 分配下一个ID

type Snowflake

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

func NewSnowflake

func NewSnowflake(workerId uint16) *Snowflake

func (*Snowflake) MustNext

func (sf *Snowflake) MustNext() int64

func (*Snowflake) Next

func (sf *Snowflake) Next() (int64, error)

type StorageType

type StorageType int8
const (
	StorageMongoDB StorageType = 1
	StorageRedis   StorageType = 2
)

Jump to

Keyboard shortcuts

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