Skip to content

TinyMurky/snowflake

Repository files navigation

Snowflake ID Generator 雪花識別碼套件

Credits

This project was inspired by and built upon several other repositories (mention in Reference Part below).
I also used OpenAI Codex to help generate and refine parts of the code.

Reference

Overview 概述

  • English: This package provides a lock-free implementation of Twitter's Snowflake ID algorithm for Go. It focuses on predictable latency, monotonic identifiers, and flexible encoding options. The generator allows you to tune node and sequence bit widths and to choose a custom epoch while keeping the classic 64-bit layout.
  • 中文: 這個套件在 Go 中實作 Twitter Snowflake 演算法,採無鎖設計以降低延遲並確保遞增的識別碼。使用者可以調整節點與序列的位元數,指定自訂的時間起點(Epoch),並享有多種編碼格式。

Design Logic 設計邏輯

  • English: Snowflake composes a 64-bit signed integer with the most significant bit fixed at zero. The remaining bits are reserved for timestamp, node identifier, and per-millisecond sequence number. This layout keeps IDs sortable and compact while supporting horizontally scaled emitters.
  • 中文: Snowflake 以 64 位帶符號整數表示,其最高位固定為 0,其餘位元依序代表時間戳、節點編號與同毫秒序號。這樣的配置讓識別碼可排序且體積小,並支援橫向擴充。

Bit Allocation 位元配置

Bits Field Description (EN) 描述(中文)
1 Sign Always 0 to keep IDs positive 永遠為 0,確保識別碼為正數
41 Timestamp (ms) Milliseconds since the configured epoch 自訂 Epoch 起算的毫秒數
10 Node ID Identifies logical node / worker 節點或工作者編號
12 Sequence Per-millisecond counter preventing collisions 同毫秒內的序號,避免碰撞

The node and sequence widths sum to 22 bits by default, but both can be tuned (still 22 bits combined) via options.

Origin snowflake from twitter

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|                        Timestamp_Mill                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Timestamp_Mill  |  DC_ID  | Mech_ID |       Step_Count      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Snowflake In this Package

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|                        Timestamp_Mill                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Timestamp_Mill  |      Node_ID      |       Step_Count      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Snowflake vs UUID Comparison 與 UUID 的比較

Property / 性質 Snowflake UUIDv7 UUIDv4
Latency 延遲 Local calculation (~tens of ns) Local calculation (~hundreds of ns) Local calculation (~hundreds of ns)
Sortability 排序性 Naturally ordered by timestamp Mostly ordered (timestamp-first) Unordered
Collision Handling 碰撞處理 Sequence resets per ms; wait for next tick Random 74-bit suffix, extremely low probability Random 122 bits, extremely low probability
High Concurrency 高併發 Up to 4096 IDs/ms/node by default; waits 1 ms when exhausted Similar per-node throughput, but no built-in back-pressure Unlimited but unordered
Payload Size 大小 64 bits (8 bytes) 128 bits (16 bytes) 128 bits (16 bytes)
Encoding 延伸性 Multiple bases (Base58/62/36/32/16/64) Typically hex or Base58 Typically hex or Base58
  • English: Snowflake excels when you need compact, ordered IDs with deterministic latency. UUIDv7 offers similar ordering but doubles the storage footprint. UUIDv4 remains useful for decentralised generation when ordering is irrelevant.
  • 中文: 若需緊湊且可排序的識別碼,Snowflake 提供最穩定的延遲。UUIDv7 雖然也可排序,但大小是 Snowflake 的兩倍。當排序不重要時,UUIDv4 仍適合完全分散式的場景。

Installation 安裝

go get github.com/TinyMurky/snowflake
  • English: Import the module in your project after fetching it.
  • 中文: 下載後即可在專案中引用此模組。

Quick Start 快速上手

package main

import (
	"fmt"
	"log"

	"github.com/TinyMurky/snowflake"
)

func main() {
	gen, err := snowflake.NewGenerator()
	if err != nil {
		log.Fatal(err)
	}

	id, err := gen.NextID(1) // node ID = 1
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(id.Base58())
}
  • English: NewGenerator defaults to Twitter's epoch, 10 node bits, and 12 sequence bits. NextID blocks briefly if a millisecond is saturated.
  • 中文: NewGenerator 預設使用 Twitter Epoch、10 位節點與 12 位序號。若同一毫秒內用量超額,NextID 會稍候至下一毫秒。

Custom Layout 自訂配置

gen, err := snowflake.NewGenerator(
	snowflake.WithNodeBits(8),
	snowflake.WithStepBits(14),
	snowflake.WithEpoch(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
)
  • English: Keep nodeBits + stepBits == 22 to match the constructor guarantees. This combination supports 256 nodes and 16384 IDs per ms.
  • 中文: 請確保 nodeBits + stepBits == 22,如上設定可支援 256 個節點與每毫秒 16,384 筆序號。

Encoding & Decoding 編解碼

  • English: Every SID supports Base58, Base62, Base36, Base32 (Crockford), Base16, and Base64 encoders plus matching Parse... helpers. Base32 is case-insensitive and accepts O/o as zero; Base64 parsing ignores padding.
  • 中文: SID 提供 Base58Base62Base36Crockford Base32Base16Base64 的編碼函式及對應解析器。Base32 解析時不分大小寫且接受 O/o 代表 0;Base64 會忽略結尾的補字元。

Testing 測試

go test ./...
  • English: Unit tests cover the bit constructor, lock-free resolver, and encoding helpers. Integration tests validate chronological ordering and include a dedicated high-concurrency stress suite that saturates the per-ms capacity and verifies recovery.
  • 中文: 單元測試涵蓋位元組合器、無鎖序號解析器與各種編解碼。整合測試則檢查整體排序特性,並包含高併發壓力測試,模擬同毫秒耗盡後的回復行為。

Contributing 貢獻

  • English: Issues and pull requests are welcome. Please accompany new behaviour with tests and update both language sections of the README when documentation changes.
  • 中文: 歡迎提出 Issue 與 PR。新增功能請附上對應測試,並更新 README 的中英文段落。

How to open documentation

  1. install pkgsite
go install golang.org/x/pkgsite/cmd/pkgsite@latest

About

package that implement Twitter Snowflake ID

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages