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

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
G
Google Developers Blog
J
Java Code Geeks
C
Check Point Blog
Last Week in AI
Last Week in AI
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
L
LangChain Blog
有赞技术团队
有赞技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 司徒正美
IT之家
IT之家
Martin Fowler
Martin Fowler
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
U
Unit 42
Jina AI
Jina AI
Microsoft Security Blog
Microsoft Security Blog
I
InfoQ

博客园 - 干炸小黄鱼

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)
    }

}