annidy / notes

0 stars 0 forks source link

Snowflake algorithm #324

Open annidy opened 2 weeks ago

annidy commented 2 weeks ago

github.com/bwmarrin/snowflake 的算法实现

// Generate creates and returns a unique snowflake ID
// To help guarantee uniqueness
// - Make sure your system is keeping accurate system time
// - Make sure you never have multiple nodes running with the same node ID
func (n *Node) Generate() ID {

    n.mu.Lock()

    now := time.Since(n.epoch).Nanoseconds() / 1000000

    if now == n.time {
                // 当时间跟上次相同时才自增加
        n.step = (n.step + 1) & n.stepMask

                // 当自增溢出时(12bit=4096),强制等待下一毫秒
        if n.step == 0 {
            for now <= n.time {
                now = time.Since(n.epoch).Nanoseconds() / 1000000
            }
        }
    } else {
                // 当时间不同时,step归0
        n.step = 0
    }

    n.time = now

    r := ID((now)<<n.timeShift |
        (n.node << n.nodeShift) |
        (n.step),
    )

    n.mu.Unlock()
    return r
}

snowflake的缺点:

  1. 需要精确的机器时间,如果回拨很容易重复
  2. node ID长度默认是10bit(1024)。需要保证id唯一,随机值、hash(IP+端口)、线程ID等都有概率重复(主要是区间太小),推荐用DB自增解决