美文网首页个人学习
全局唯一ID - snowflake

全局唯一ID - snowflake

作者: bysir | 来源:发表于2019-11-17 17:17 被阅读0次

    为什么需要全局唯一ID

    比如以下

    分布式下唯一ID

    • 如果数据库分了库/表, 那么表的自增主键就不再唯一, 这时候就需要一个全局唯一的ID生成器才能保证唯一.
    • 可以用来作为事务ID等需要保证唯一的业务 (事务ID可以用来确保幂等)

    预生成ID

    有些业务下需要提前生成唯一ID, 这也是表的自增主键不能满足的需求.

    snowflake

    生成全局唯一ID有多种方法(可以搜到), 比如使用额外的数据库或者UUID, 但笔者认为性能更好 适用性更广的是snowflake算法.

    snowflake是twitter开源的分布式ID生成算法, GITHUB在此.

    我们如果要在代码中使用还需要根据语言实现它的算法, 笔者使用编程语言是golang, 幸运的是GITHUB上已经有了实现好的库, 如

    • github.com/bwmarrin/snowflake

    用法也十分简单, 这里贴上readme-usage看一眼, 更多使用方法请参看官方库-github.com/bwmarrin/snowflake.

    package main
    
    import (
        "fmt"
    
        "github.com/bwmarrin/snowflake"
    )
    
    func main() {
    
        // Create a new Node with a Node number of 1
        node, err := snowflake.NewNode(1)
        if err != nil {
            fmt.Println(err)
            return
        }
    
        // Generate a snowflake ID.
        id := node.Generate()
    
        // Print out the ID in a few different ways.
        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())
    
        // Print out the ID's timestamp
        fmt.Printf("ID Time  : %d\n", id.Time())
    
        // Print out the ID's node number
        fmt.Printf("ID Node  : %d\n", id.Node())
    
        // Print out the ID's sequence number
        fmt.Printf("ID Step  : %d\n", id.Step())
    
      // Generate and print, all in one.
      fmt.Printf("ID       : %d\n", node.Generate().Int64())
    }
    

    时钟回拨问题

    如果你使用了golang1.9+ 并且使用了最新的bwmarrin/snowflake库, 那么这个问题已经不存在了, 详情看这个issue:
    https://github.com/bwmarrin/snowflake/issues/20

    这是Golang的提案: Proposal: Monotonic Elapsed Time Measurements in Go

    相关文章

      网友评论

        本文标题:全局唯一ID - snowflake

        本文链接:https://www.haomeiwen.com/subject/dptubctx.html