惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
人人都是产品经理
人人都是产品经理
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
小众软件
小众软件
B
Blog
博客园 - 叶小钗
Microsoft Azure Blog
Microsoft Azure Blog
Apple Machine Learning Research
Apple Machine Learning Research
A
About on SuperTechFans
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Recent Announcements
Recent Announcements
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
V
V2EX

博客园 - 干炸小黄鱼

timex 处理时间戳 gorm-gen go 雪花算法 golang每日一库--协程池库ants golang每日一库--json解析库gjson python高级编程-asyncio python高级编程-condition python高级编程-event python装饰器-自动重试 EAP系统 go实现实现 SECS/GEM 协议 设备通信协议 SECS go项目使用Jenkins进行CICD go操作ES mongo db聚合查询 go如何使用mongodb Apache ShardingSphere paxos and raft (分布式一致性算法) go使用zookeeper分布式锁以及和redis差异 go使用 seata 示例 Alibaba 分布式事务 Seata go中使用saga go中使用TCC示例 分布式事务TCC 熔断器 Hystrix OR Sentinel k8s下部署consul and etcd Consul OR Etcd 【力扣hot100】双指针-盛水最多的容器 【力扣hot100】滑动窗口-最小覆盖子串 shell脚本合集
分布式id生成器
干炸小黄鱼 · 2025-05-20 · via 博客园 - 干炸小黄鱼

github.com/bwmarrin/snowflake 和 sonyflake

是一个相当轻量化的 snowflake 的 Go 实现。其文档对各位使用的定义如下图所示:

此库和标准的 snowflake 实现方式全完一致,使用也比较简单:

package main

import (
    // 示例代码只导入提供核心功能的package,其他内置package自行导入,下同
    "github.com/bwmarrin/snowflake"
)

func main() {
    node, err := snowflake.NewNode(1)
    if err != nil {
        println(err.Error())
        os.Exit(1)
    }

    for i := 0; i < 20; i++ {
        id := node.Generate()

        fmt.Printf("Int64  ID: %d\n", id)
        fmt.Printf("String ID: %s\n", id)
        fmt.Printf("Base2  ID: %s\n", id.Base2())
        fmt.Printf("Base64 ID: %s\n", id.Base64())

        fmt.Printf("ID Time  : %d\n", id.Time())

        fmt.Printf("ID Node  : %d\n", id.Node())

        fmt.Printf("ID Step  : %d\n", id.Step())

        fmt.Println("---------------------------------------------")
    }

}
var (
    // Epoch is set to the twitter snowflake epoch of Nov 04 2010 01:42:54 UTC in milliseconds
    // You may customize this to set a different epoch for your application.
    Epoch int64 = 1288834974657

    // NodeBits holds the number of bits to use for Node
    // Remember, you have a total 22 bits to share between Node/Step
    NodeBits uint8 = 10

    // StepBits holds the number of bits to use for Step
    // Remember, you have a total 22 bits to share between Node/Step
    StepBits uint8 = 12
)

Epoch为起始时间,NodeBits是实例id的位长,StepBits是自增id的位长。

sonyflake

sonyflake 同样是受 Twitter 的 snowflake 启发而来,但 sonyflake 侧重于多主机/实例的生命周期和性能,所以与 snowflake 使用不同的位分配

sonyflake 的优点和缺点:

  • 比 snowflake 更长的生命周期,174年 > 69年
  • 能运行在更多的实例上,216 > 210
  • 生成 ID 速度比 snowflake 慢,10 毫秒内最多生成 28 个(snowflake 1 毫秒内最多生成 212 个)

sonyflake 在启动阶段需要配置参数:

func NewSonyflake(st Settings) *Sonyflake
Settings数据结构如下:

type Settings struct {
    StartTime      time.Time
    MachineID      func() (uint16, error)
    CheckMachineID func(uint16) bool
}

StartTime起始时间,默认值为2014-09-01 00:00:00 +0000 UTC
MachineID是一个返回实例 ID 的函数,如果不定义此函外,默认用本机ip 的低16位
CheckMachineID验证实例 ID / 计算机ID 的唯一性,返回true时才创建

package main

import (
    "github.com/sony/sonyflake"
)

func getMachineID() (uint16, error) {
    var machineID uint16 = 6
    return machineID, nil
}

func checkMachineID(machineID uint16) bool {
    existsMachines := []uint16{1, 2, 3, 4, 5}
    for _, v := range existsMachines {
        if v == machineID {
            return false
        }
    }
    return true
}

func main() {
    t, _ := time.Parse("2006-01-02", "2021-01-01")
    settings := sonyflake.Settings{
        StartTime:      t,
        MachineID:      getMachineID,
        CheckMachineID: checkMachineID,
    }

    sf := sonyflake.NewSonyflake(settings)

    for i := 0; i < 10; i++ {
        id, err := sf.NextID()
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
        fmt.Println(id)
    }

}