golang极速全局唯一ID生成器插件库wuid的使用

Golang极速全局唯一ID生成器插件库WUID的使用

概述

  • WUID是一个通用唯一标识符生成器
  • WUID比传统UUID快得多,每个WUID实例每秒可以生成1亿个唯一标识符
  • 本质上,WUID按顺序生成64位整数,高28位从数据源加载,目前支持Redis、MySQL、MongoDB和Callback
  • 只要所有WUID实例共享相同数据源或每组具有不同的section ID,就能保证唯一性
  • 当低36位即将用完时,WUID会自动更新高28位
  • WUID是线程安全的,并且无锁
  • 支持混淆

性能基准

BenchmarkWUID           159393580          7.661 ns/op        0 B/op       0 allocs/op
BenchmarkRand           100000000         14.95 ns/op         0 B/op       0 allocs/op
BenchmarkTimestamp      164224915          7.359 ns/op        0 B/op       0 allocs/op
BenchmarkUUID_V1        23629536          43.42 ns/op         0 B/op       0 allocs/op
BenchmarkUUID_V2        29351550          43.96 ns/op         0 B/op       0 allocs/op
BenchmarkUUID_V3         4703044         254.2 ns/op        144 B/op       4 allocs/op
BenchmarkUUID_V4         5796310         210.0 ns/op         16 B/op       1 allocs/op
BenchmarkUUID_V5         4051291         310.7 ns/op        168 B/op       4 allocs/op
BenchmarkRedis              2996       38725 ns/op          160 B/op       5 allocs/op
BenchmarkSnowflake       1000000        2092 ns/op            0 B/op       0 allocs/op
BenchmarkULID            5660170         207.7 ns/op         16 B/op       1 allocs/op
BenchmarkXID            49639082          26.21 ns/op         0 B/op       0 allocs/op
BenchmarkShortID         1312386         922.2 ns/op        320 B/op      11 allocs/op
BenchmarkKsuid          19717675          59.79 ns/op         0 B/op       0 allocs/op

安装

go get -u github.com/edwingeng/wuid

使用示例

Redis示例

import "github.com/edwingeng/wuid/redis/v8/wuid"

newClient := func() (redis.UniversalClient, bool, error) {
    var client redis.UniversalClient
    // 初始化Redis客户端
    return client, true, nil
}

// 初始化
w := NewWUID("alpha", nil)
err := w.LoadH28FromRedis(newClient, "wuid")
if err != nil {
    panic(err)
}

// 生成ID
for i := 0; i < 10; i++ {
    fmt.Printf("%#016x\n", w.Next())
}

MySQL示例

import "github.com/edwingeng/wuid/mysql/wuid"

openDB := func() (*sql.DB, bool, error) {
    var db *sql.DB
    // 初始化数据库连接
    return db, true, nil
}

// 初始化
w := NewWUID("alpha", nil)
err := w.LoadH28FromMysql(openDB, "wuid")
if err != nil {
    panic(err)
}

// 生成ID
for i := 0; i < 10; i++ {
    fmt.Printf("%#016x\n", w.Next())
}

MongoDB示例

import "github.com/edwingeng/wuid/mongo/wuid"

newClient := func() (*mongo.Client, bool, error) {
    var client *mongo.Client
    // 初始化MongoDB客户端
    return client, true, nil
}

// 初始化
w := NewWUID("alpha", nil)
err := w.LoadH28FromMongo(newClient, "test", "wuid", "default")
if err != nil {
    panic(err)
}

// 生成ID
for i := 0; i < 10; i++ {
    fmt.Printf("%#016x\n", w.Next())
}

Callback示例

import "github.com/edwingeng/wuid/callback/wuid"

callback := func() (int64, func(), error) {
    var h28 int64
    // 自定义逻辑获取h28值
    return h28, nil, nil
}

// 初始化
w := NewWUID("alpha", nil)
err := w.LoadH28WithCallback(callback)
if err != nil {
    panic(err)
}

// 生成ID
for i := 0; i < 10; i++ {
    fmt.Printf("%#016x\n", w.Next())
}

MySQL表创建

CREATE TABLE IF NOT EXISTS `wuid` (
    `h` int(10) NOT NULL AUTO_INCREMENT,
    `x` tinyint(4) NOT NULL DEFAULT '0',
    PRIMARY KEY (`x`),
    UNIQUE KEY `h` (`h`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

选项

  • WithSection 在每个生成的数字上标记一个section ID,section ID必须在[0, 7]之间
  • WithStep 设置每个生成数字的步长和下限
  • WithObfuscation 启用数字混淆

注意事项

强烈建议将logger传递给wuid.NewWUID并密切关注包含"renew failed"的警告。这表示低36位将在几小时到几百小时内用完,并且续订程序因某些原因失败。WUID将进行多次续订尝试,直到成功为止。


更多关于golang极速全局唯一ID生成器插件库wuid的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang极速全局唯一ID生成器插件库wuid的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang极速全局唯一ID生成器WUID使用指南

WUID是一个高性能的全局唯一ID生成器Golang库,它比传统的UUID或snowflake算法更快,同时保证分布式环境下的唯一性。

WUID核心特点

  1. 极高性能:本地生成不依赖网络请求
  2. 全局唯一:通过中央服务分配区间保证唯一性
  3. 短小精悍:生成的ID比UUID更短
  4. 支持多种存储:Redis、MySQL、PostgreSQL等

安装

go get github.com/edwingeng/wuid

基本使用示例

1. 使用Redis作为后端存储

package main

import (
	"fmt"
	"github.com/edwingeng/wuid/redis/wuid"
)

func main() {
	// 创建Redis客户端
	w := wuid.NewWUID("default", nil)
	
	// 配置Redis连接
	err := w.LoadH28FromRedis("127.0.0.1:6379", "", "wuid")
	if err != nil {
		panic(err)
	}
	
	// 生成ID
	for i := 0; i < 10; i++ {
		fmt.Println(w.Next())
	}
}

2. 使用MySQL作为后端存储

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/edwingeng/wuid/mysql/wuid"
)

func main() {
	// 创建MySQL客户端
	db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
	if err != nil {
		panic(err)
	}
	defer db.Close()
	
	// 初始化WUID
	w := wuid.NewWUID("default", nil)
	err = w.LoadH28FromMysql(db, "wuid")
	if err != nil {
		panic(err)
	}
	
	// 生成ID
	for i := 0; i < 10; i++ {
		fmt.Println(w.Next())
	}
}

高级配置

自定义ID格式

WUID生成的ID默认是int64类型,包含以下部分:

  • 28位高位:由中央服务分配,保证全局唯一
  • 24位低位:本地生成的自增序列
  • 12位保留位
// 自定义配置
w := wuid.NewWUID("default", &wuid.WUIDOptions{
	Section: 5,       // 使用第5个数据段
	H28Verifier: func(h28 int64) error {
		// 验证高位值
		return nil
	},
})

性能优化建议

  1. 批量预取:可以配置预取一定数量的ID到本地缓存

    w := wuid.NewWUID("default", &wuid.WUIDOptions{
        Prefetch: 1000, // 预取1000个ID
    })
    
  2. 多段分配:大规模部署时可使用不同section

    w1 := wuid.NewWUID("service1", nil) // 默认section 0
    w2 := wuid.NewWUID("service2", &wuid.WUIDOptions{Section: 1})
    

与传统ID生成方案对比

特性 WUID UUID Snowflake
生成速度 极快 中等
存储空间 8字节 16字节 8字节
有序性
分布式环境唯一性 需要配置
依赖外部服务 可选

使用场景推荐

  1. 高吞吐日志ID:需要快速生成大量唯一标识
  2. 分布式事务ID:跨服务的唯一标识
  3. 数据库主键:比自增ID更适合分布式环境
  4. 短链接生成:比UUID更短的唯一标识

注意事项

  1. 使用中央存储(Redis/MySQL)时,需要确保其高可用
  2. 默认配置下,单机每秒可生成约1600万个ID
  3. 在容器化环境中,注意合理配置section以避免冲突

WUID在保证高性能的同时提供了良好的分布式支持,是Golang项目中生成唯一ID的优秀选择。

回到顶部