snowflake 算法生成的 id 也能重复? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
sunmoon1983
V2EX    Go 编程语言

snowflake 算法生成的 id 也能重复?

  •  1
     
  •   sunmoon1983 2020-02-15 20:23:20 +08:00 5658 次点击
    这是一个创建于 2069 天前的主题,其中的信息可能已经有所发展或是发生改变。

    客户端代码:

    func GenerateID() (string, error) { c := connect.Instance() //连接 grpc cc, cancel := c.ServerClient() defer cancel() //生成 id r, err := cc.GenerateSnowflakeID(c.Ctx, &serv.GenerateSnowflakeRequest{WorkID:"1"}) if err != nil { return "", err } return r.GetMessage(), err } func main() { data := "" for i:=0;i<=100;i++{ id, err := GenerateID() str := gconv.String(id) fmt.Println("ID(运行到第"+gconv.String(i+1)+"条):"+str+",长度:"+gconv.String(len(str))) if strings.Contains(data,","+str+","){ fmt.Println("ID 重复(运行到第"+gconv.String(i+1)+"条):"+str) break }else{ if err != nil{ fmt.Println(err.Error()) } data = data+","+str+"," } } } 

    生成结果

    sunmoondeMacBook-Pro:client_test sunmoon$ go run main.go ID(运行到第 1 条):1581769199913537536,长度:19 ID(运行到第 2 条):1581769199913537536,长度:19 ID 重复(运行到第 2 条):1581769199913537536 

    服务端代码

    // GenerateSnowflakeID 生成 ID func (s *Server) GenerateSnowflakeID(ctx context.Context, in *serv.GenerateSnowflakeRequest) (re *serv.GenerateReply, err error) { gen, err := snowflake.New().SetWorkerID(gconv.Int64(in.GetWorkID())).Init() if err != nil { glog.Line(true).Println(err.Error()) return } id, err := gen.Generate() if err != nil { glog.Line(true).Println(err.Error()) return } //id := s.GetWuid() re = &serv.GenerateReply{Message: gconv.String(id)} return } 
    11 条回复    2020-04-23 10:49:53 +08:00
    lqs
        1
    lqs  
       2020-02-15 20:38:06 +08:00
    每次都 Init 当然会一样了
    OllyDebug
        2
    OllyDebug  
       2020-02-15 22:20:18 +08:00 via iPhone
    代码的锅
    jingege
        3
    jingege  
       2020-02-15 22:36:15 +08:00 via Android
    我知道有个 nug,但是其实很容易发现,我决定先不告诉你
    stevenhawking
        4
    stevenhawking  
       2020-02-15 23:05:03 +08:00
    @jingege 我知道你这句话有个 nug,但是其实很容易发现,我决定先不告诉你
    swulling
        5
    swulling  
       2020-02-16 01:40:01 +08:00 via iPhone
    用法有问题,时间 workerID 序列号都相同
    sunmoon1983
        6
    sunmoon1983  
    OP
       2020-02-16 08:02:12 +08:00
    @lqs init 里面有判断,如果已经初始化了
    if sfg.isHaveInit {
    return sfg, nil
    }
    sunmoon1983
        7
    sunmoon1983  
    OP
       2020-02-16 08:02:55 +08:00
    @swulling 大老,指点一下?循环里面要怎么用?
    sunmoon1983
        8
    sunmoon1983  
    OP
       2020-02-16 08:12:00 +08:00
    感谢大家,
    @lqs 谢谢,我把 INIT 拿出来就可以了
    beiping96
        9
    beiping96  
       2020-02-17 13:19:02 +08:00
    另外还有一个点,如果生成 snowflake ID 的节点 在小于几 ms 内完成重启的话,也是会发生重复的
    yuechen323
        11
    yuechen323  
       2020-04-23 10:49:53 +08:00
    基于 SnowFlake 简单是简单, 但是需要二次开发
    在每个应用内, 多线程情况下, 且高并发是一定会出现重复的, 因此生成 id 的服务一定要做成独立的服务
    且生成 id 的进程一定是单线程, 可以用池化技术进行预分配 id 来优化速度
    如果 id 服务要做成集群, 那么 dataCenterId 一定设置成不一样的, 这就变成了有状态服务
    有状态服务如何优化呢?
    可以在启动 id 服务的时候, 从 redis 啊, zookeeper 里面原子的获取自增 id 来实现
    这样就可以无脑的部署多个点了
    Peace~
    关于     帮助文档     自助推广系统     博客     API     FA     Solana     3167 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 00:33 PVG 08:33 LAX 17:33 JFK 20:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86