Golang Go语言:昨晚用 Golang 写了个 ID 生成服务,分享给大家

go-id-alloc

Golang+Mysql 实现的分布式 ID 生成服务

特性

  • 高性能:分配 ID 只访问内存
  • 分布式:横向扩展,理论无上限
  • 高可靠:Mysql 持久化,故障恢复快
  • 唯一性:生成 64 位整形,整体递增,永不重复
  • 易用性:可自定义 ID 起始位置,对外 HTTP 服务
  • 可运维性:提供健康检查接口,通过负载均衡自动摘除故障节点

地址: https://github.com/owenliang/go-id-alloc


Golang Go语言:昨晚用 Golang 写了个 ID 生成服务,分享给大家

更多关于Golang Go语言:昨晚用 Golang 写了个 ID 生成服务,分享给大家的实战教程也可以访问 https://www.itying.com/category-94-b0.html

37 回复

唯一性:生成 64 位整形,整体递增,永不重复 太长

更多关于Golang Go语言:昨晚用 Golang 写了个 ID 生成服务,分享给大家的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


实际情况中来讲不递增 id 会好一些

按业务规则生成会好一些

id 最好不要带业务规则,这是 DB schema 的设计原则之一

谁的原则

> 高性能:分配 ID 只访问内存

多个服务器怎么保证递增?

看代码喽

分布式,只访问内存,还能保证严格递增,图灵奖级别的成就啊。

不是严格。。我的措辞是整体递增,哈哈

用 redis 的 increment 生成 id 比这个 mysql 方便吧?

直接用 uuid,自增 id 最麻烦的就是可猜测。。。。

SnowFlake

理论无上限,永不重复
就这两条,我能喷死你。。。

楼上正解,现阶段 twitter snowflake 算法算是最为可用的方案。。。

我就很好奇你能喷出啥。。

snowflake 还需要分享给大家么?

编码长度是有限的,只要执行足够多次就会出现重复或者程序不正常。

用带有硬件信息的 GUID 算法就好了啊,这样不同电脑生成的就会不同了。

鉴于不同意见较多,不再一一回复大家,关于分布式 ID 方案优劣势参考: https://tech.meituan.com/MT_Leaf.html。

链接多了个“。”

肯定楼主的动手出代码
都用 golang 还再加上 mysql 就为了分布式 uuid 实现起来觉得有点重了 依赖了 mysql,考虑到就帮,那 mysql 高可用也需要保证了吧

只能有 2^64 个 id 吧,永不重复有点过了

很有道理

对 云或者公司都有能力提供高可用 mysql

有序 id 还是有用的

snowflake 加原子钟,直接硬件解决时间问题

便宜的原子钟才几百块

看了下代码,仿佛核心是先分区( segments ),仿佛也可称为分片,然后根据每个分片根据自己的分区信息自己内部进行 ID 递增。


<br>func (alloc *Alloc)NextId() (int64, error) {<br> alloc.mutex.Lock()<br> defer alloc.mutex.Unlock()<br><br> if len(alloc.segments) &gt; 0 {<br> id := alloc.segments[0].left + alloc.segments[0].offset<br> alloc.segments[0].offset++<br> if id + 1 &gt;= alloc.segments[0].right {<br> alloc.segments = append(alloc.segments[:0], alloc.segments[1:]...)<br> }<br> return id, nil<br> } else {<br> return 0, errors.New("no more id")<br> }<br>}<br>

套用日本中二片里面自吹的话,最简单是 ID 生成器,最难也是 ID 生成器。

如果我理解没错的话,
你这套代码只能保证某个分区内递增,不能保证所有分区一起递增。
每次请求不能落盘,不能记录已分配的 ID,或许可以采用异步解决,但是遇到灾难性故障基本会出现重复的情况。
64 位整形仍然不能保证不重复。

目前来看,UUID 中 snowflake 才是终极方案,自增 ID 仍然数 TIDB 那套比较靠谱,虽然他不能保证连续,但是至少自增。

而且,mutex.lock 和 unlock 中间代码行数比较多,单个分片可能有性能问题。go 语言是否可以用 atomic.incr 那一套逻辑解决。

我只是稍微看了点代码,如有理解错误请提。

你理解错了,再看看代码吧。

问个问题,都记录在内存中,有容灾处理么?分布式节点中,多个节点 down 后,如何解决脑裂问题呢?

人家仔细看了代码,而且贴出来了自己的分析,即使你觉得错,多写两句告诉别人具体哪里你觉得有问题才是讨论的态度吧?什么都不说直接让人再看代码?别人估计不会再看了

看不看与我何干?感兴趣自己看,还有管闲事的,真是笑尿了

就你这个态度,真没必要把你的什么项目贴出来,指望别人不由分说就一脸膜拜交口称赞?你自嗨去吧

蛤蛤蛤,没必要的。

至于态度,也还好吧。

但是第二天 astaxie 发了每日链接,有他这个 ID 生成器的设计的文章,感觉还好。

他自己也贴在一楼了。

毕竟有产出,有益于社会。

不用苛求太多。

我要是好不容易写个东西然后被楼上这么喷,我估计我也会毛的。

你好,很高兴看到你使用Golang开发了一个ID生成服务。在Go语言中,实现一个高效、可靠的ID生成服务是一个常见的需求,特别是在分布式系统中。以下是一些关于你的ID生成服务的建议和思考:

  1. 唯一性与顺序性:确保生成的ID在全局范围内是唯一的,并且如果业务需要,也可以考虑保持一定的顺序性。常见的解决方案包括使用UUID、雪花算法(Snowflake)等。

  2. 性能与并发:在高并发环境下,ID生成服务的性能至关重要。确保你的服务能够处理大量的并发请求,并且不会因为竞争资源而导致性能下降。

  3. 持久化与恢复:如果服务需要持久化ID的生成状态(例如,在重启后能够继续生成连续的ID),请确保有一个可靠的持久化机制。

  4. 安全性:如果ID生成服务涉及到敏感信息(例如,用户ID等),请确保服务的安全性,防止被恶意攻击者利用。

  5. 可扩展性与容灾:考虑服务的可扩展性和容灾能力。例如,可以使用负载均衡和故障转移机制来提高服务的可用性和稳定性。

  6. 代码优化:检查你的代码,确保没有内存泄漏、不必要的资源消耗等问题。同时,保持代码的清晰和可读性,便于后续的维护和扩展。

最后,如果你愿意分享更多的代码细节或遇到的问题,我们可以一起探讨如何进一步优化你的ID生成服务。祝你在Go语言的开发之路上越走越远!

回到顶部