zheng-ji / goSnowFlake

一个实现 Twitter SnowFlake 算法 的 Go 分布式 UID 生成器.A threadsafe unique ID generator inspired by Twitter SnowFlake theory
MIT License
364 stars 75 forks source link

ID在某些情况下重复 #11

Closed elevenstyle closed 6 years ago

elevenstyle commented 6 years ago

window环境下正常,部署到centos下出现了生成ID重复的情况 以下是插入mysql报错日志 [ORM]2018/09/06 11:03:08 -[Queries/default] - [ OK / db.Exec / 0.4ms] - [INSERT INTO pms_groups_permission (id, groupid, permissionid) VALUES (?, ?, ?)] - 257530689124044800, 1468755197309162134, 64815327690625024 [ORM]2018/09/06 11:03:08 -[Queries/default] - [FAIL / db.Exec / 0.2ms] - [INSERT INTO pms_groups_permission (id, groupid, permissionid) VALUES (?, ?, ?)] - 257530689124044800, 1468755197309162134, 42334379363536896 - Error 1062: Duplicate entry '257530689124044800' for key 'PRIMARY' [ORM]2018/09/06 11:03:08 -[Queries/default] - [FAIL / db.Exec / 0.2ms] - [INSERT INTO pms_groups_permission (id, groupid, permissionid) VALUES (?, ?, ?)] - 257530689124044800, 1468755197309162134, 42334539376234496 - Error 1062: Duplicate entry '257530689124044800' for key 'PRIMARY' 生成ID代码: func SnowFlakeId() int64 { iw, _ := goSnowFlake.NewIdWorker(1) if id, err := iw.NextId(); err != nil { return 0 } else { return id } }

zheng-ji commented 6 years ago

你好,我将你的ID 反着解开出来

package main
import (
    "fmt"
    "github.com/zheng-ji/goSnowFlake"
)

func main() {
    var id int64
    id = 257530689124044800
    t, ts, workid, seq := goSnowFlake.ParseId(id)
    fmt.Printf(t) //
    fmt.Println(ts)
    fmt.Println(workid)
    fmt.Println(seq)
}

得到的是

时间:2018-09-06 03:03:08.976 +0000 UTC
时间戳:1536202988976
workid:1
sequence:0

可以看到sequence 是 0 说明没有发生时间上冲突 怀疑你是不是启用了多个 goSnowFlake.NewIdWorker(1) 呢? 应该是需要确保全局一个 IdWorker.

另外:发现你的服务器时间有些不准确。我解开之后发现的是:2018-09-06 03:03:08.976 +0000 UTC 与你日志贴的时间有一些差别.

同时 我刚刚fix了 会生成重复ID的隐藏可能。 你可以重新go get 再试试。

elevenstyle commented 6 years ago

thk