Snowflake-Me
English | 简体中文
A high-performance, highly concurrent, distributed Snowflake ID generator in Rust.
This implementation is lock-free, designed for maximum throughput and minimum latency on multi-core CPUs.
Highlights
- Lock-Free Concurrency: Uses
AtomicU64and CAS (Compare-And-Swap) operations to manage internal state, completely eliminating the overhead ofMutexcontention and context switching. - High Performance: The lock-free design makes ID generation extremely fast, performing exceptionally well under high concurrency.
- Highly Customizable: The
Builderpattern allows you to flexibly configure:start_time: The epoch timestamp to shorten the time component of the generated ID.machine_idanddata_center_id: Identifiers for your machines and data centers.- Bit lengths for each component (
time,sequence,machine_id,data_center_id).
- Smart IP Fallback: With the
ip-fallbackfeature enabled, ifmachine_idordata_center_idare not provided, the system will automatically use the machine's local IP address.- Supports both IPv4 and IPv6: It prioritizes private IPv4 addresses and falls back to private IPv6 addresses if none are found.
- Conflict-Free: To ensure uniqueness,
machine_idanddata_center_idare derived from distinct parts of the IP address:- IPv4:
data_center_idfrom the 3rd octet,machine_idfrom the 4th octet. - IPv6:
data_center_idfrom the 7th segment,machine_idfrom the 8th (last) segment.
- IPv4:
- Thread-Safe:
Snowflakeinstances can be safely cloned and shared across threads. Cloning is a lightweight operation (just anArcreference count increment).
Snowflake ID Structure
The generated ID is a 64-bit unsigned integer (u64) with the following default structure:
+-------------------------------------------------------------------------------------------------+
| 1 Bit (Unused, Sign Bit) | 41 Bits (Timestamp, ms) | 5 Bits (Data Center ID) | 5 Bits (Machine ID) | 12 Bits (Sequence) |
+-------------------------------------------------------------------------------------------------+
- Sign Bit (1 bit): Always 0 to ensure the ID is positive.
- Timestamp (41 bits): Milliseconds elapsed since your configured
start_time. 41 bits can represent about 69 years. - Data Center ID (5 bits): Allows for up to 32 data centers.
- Machine ID (5 bits): Allows for up to 32 machines per data center.
- Sequence (12 bits): The number of IDs that can be generated per millisecond on a single machine. 12 bits allow for 4096 IDs per millisecond.
Note: The bit lengths of all components are customizable via the Builder, but their sum must be 63.
Quick Start
1. Add Dependency
Add this library to your Cargo.toml:
Important Notice
The dependency name has been changed from 'snowflake_me' to 'snowflake-me' in version '0.5.0'. Please use the new name in yourCargo.toml:= "0.8.0"No Rust code changes are required; only update the dependency name in
Cargo.toml.
To enable the IP address fallback feature, enable the
ip-fallbackfeature:
[] = { = "0.8.0", = ["ip-fallback"] }
Feature Flags
| Feature | Description |
|---|---|
ip-fallback |
Auto-detect machine_id and data_center_id from local network interfaces (IPv4/IPv6). |
serde |
Serde Serialize/Deserialize for SnowflakeId (u64) and SnowflakeIdString (string). |
tracing |
Structured logging via tracing at key points (ID generation, clock drift, etc.). |
metrics |
Counters and gauges via metrics crate for observability. |
full |
Enables all optional features at once. |
2. Basic Usage
use Snowflake;
3. Multi-threaded Usage
Snowflake instances can be efficiently cloned and shared between threads.
use Snowflake;
use thread;
use Arc;
use HashSet;
4. Decomposing an ID
You can decompose a Snowflake ID back into its components for debugging or analysis.
use Snowflake;
5. Clock Drift Protection
If the system clock moves backward (e.g., due to NTP adjustments), the generator handles it based on the configured strategy. By default, it busy-waits until the clock catches up.
use ;
Available strategies:
ClockDriftStrategy::Wait(default) — Busy-wait until the clock catches up. Optionally setmax_clock_drift_msto fail if the drift is too large.ClockDriftStrategy::Error— ReturnError::ClockDriftimmediately on backward drift.ClockDriftStrategy::LastTimestamp— Reuse the last known timestamp. IDs remain unique but timestamps become approximate.
Contributing
Issues and Pull Requests are welcome.
License
This project is dual-licensed under the MIT and Apache 2.0 licenses.