资讯专栏INFORMATION COLUMN

分布式系统全局发号器的几点思考

dayday_up / 3614人阅读

摘要:为什么需要发号器在分布式系统中,经常需要对大量的数据消息请求等进行唯一标识,例如对于分布式系统,服务间相互调用需要唯一标识,调用链路分析,日志追踪的时候需要使用这个唯一标识。

原文链接:何晓东 博客

文章起源于 康神交流群的 panda大佬和boss li关于发号器的一些交流,特此感谢让我们学到了新知识。
为什么需要发号器

在分布式系统中,经常需要对大量的数据、消息、http 请求等进行唯一标识,例如:对于分布式系统,服务间相互调用需要唯一标识,调用链路分析,日志追踪的时候需要使用这个唯一标识。此时需要一个全局唯一的 ID。

需要什么样子的发号器

持久化

要满足长期全局唯一,持久化是必须的,肯定不能让已经使用的再次产生一遍,同时需要强一致性。可用选择存储在 Redis 或者 Etcd 中。

高可用

这个时候需要提供发号器服务的机器主从同步,能够在主服务器宕机的时候,自动选择从服务器,切换过程中,发号器生成的 ID 可能不连续,服务正常就可以。

其他特性

主要是看具体业务了,需要认证和权限控制都是可选的,可用在请求层限制来源 IP,只允许固定的 IP 访问。
发号器的几种常用方案
UUID

UUID 是 Universally Unique Identifier 的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符,UUID 是16字节128位长的数字,通常以36字节的字符串表示,比如:3F2504E0-4F89-11D3-9A0C-0305E82C3301。

UUID经由一定的算法机器生成,为了保证 UUID 的唯一性,规范定义了包括网卡 MAC 地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素,以及从这些元素生成 UUID 的算法。UUID 的复杂特性在保证了其唯一性的同时,意味着只能由计算机生成。

优缺点: 本地生成,性能高,延迟低,位数长,不适用当作索引字段,同时是无序的,难以根据特征分析趋势。

类snowflake算法

snowflake是twitter开源的分布式ID生成算法,其核心思想为,一个long型的ID:

41bit作为毫秒数 - 10bit作为机器编号 - 12bit作为毫秒内序列号

算法单机每秒内理论上最多可以生成1000*(2^12),也就是400W的ID,

优缺点: 整个 ID 都是自增的,这个非常适合查看趋势,同时生成不依赖于第三方系统,可靠性很高,可调整性也很高。缺点就是严重依赖机器时钟。

基于MySQL的发号器

字段设置 auto_increment_incrementauto_increment_offset 来保证 ID 自增,每次业务使用下列 SQL 读写 MySQL 得到 ID。

begin;
REPLACE INTO Tickets64 (stub) VALUES ("a");
SELECT LAST_INSERT_ID();
commit;

为了保证高可用,需要有多台 MySQL 机器,也需要为每台机器设置不同的自增起始值和步长,例如:

# TicketServer1:
auto-increment-increment = 2
auto-increment-offset = 1

# TicketServer2:
auto-increment-increment = 2
auto-increment-offset = 2

优缺点: 简单可靠,成本很小,由专业 DBA 进行维护就可以的。ID 单调递增,有合适的业务是最好的。缺点就是强依赖于数据库,修改起点和步长优点困难,同时也需要额外保证数据库的稳定可用。每次请求都去额外读写数据库的情况下,造成数据库压力很大,需要消耗很多资源。

以上就是最常用的三种全局唯一 ID 生成方案,采用较多的是类 snowflake 的方案,如果请求数列不是很高,可以调低时间的精度等,灵活性很高。生成的 ID 时间趋势自增,甚至可以用来做索引字段,占用空间较小。后期对数据进行分析的时候也很方便。
生产环境唯一ID的使用

类 snowflake 的方案,会采用请求时生成的方式,无法提前生成。

基于 MySQL 的发号器,或者 uuid 模式的,可用提前生成一大批数据,根据业务去定生成数量,放到内存,MQ 或者 Redis List中,业务申请唯一 ID 的时候,直接从其中弹一个出来。同时加一个异步定时任务,固定时间计算一下队列中剩余的唯一 ID 数量,数量不足时及时的再次生成一大批,加入到备选队列。

Go snowflake的demo:

参考文章:

有赞技术团队文章 - 发号器

CSDN文章

美团分布式ID生成

Go snowflake包

一如既往,推荐几个 高质量课程,你学到新东西,我赚点佣金,大家都是赢家。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31787.html

相关文章

  • php + redis + lua 实现一个简单的号器(1)-- 原理篇

    摘要:出于以上两个原因,我们需要自己的发号器来产生。与此同时,为了保证执行,具有原子性,我们使用来进行实现。由于能力和水平有限,难免会有纰漏,希望及时指出。参考文章分布式生成器实现上实现原理 1、为什么要实现发号器 很多地方我们都需要一个全局唯一的编号,也就是uuid。举一个常见的场景,电商系统产生订单的时候,需要有一个对应的订单编号。在composer上我们也可以看到有很多可以产生uuid...

    rottengeek 评论0 收藏0
  • 短链接系统的设计

    摘要:映射机制对每个长链接,使用一个小于亿的整数标记。短链接不够用或者虽然我们的短链接可以表示亿个资源,貌似很多,但是对于大型系统,如银行,搜索引擎等等,还是非常少的。解决既然位短链接不够用,那可以多使用几位,比如位,大概等于亿但是,总是有限的。 引用、参考:短 URL 系统是怎么设计的?iammutex的回答 什么是短链接 表示较短的URL(是不是废话?....) 为什么需要短链接 不同...

    fish 评论0 收藏0
  • 短链接原理分析

    摘要:举个例子,第一个进来的链接发号器发号,对应的短链接为,第二个进来的链接发号器发号,对应的短链接为,以此类推。这样一来会导致一条长链接对应多条短链接的情况出现,不仅浪费存储空间,又浪费发号器资源。 1. 什么是短链接 顾名思义,短链接即是长度较短的网址。通过短链接技术,我们可以将长度较长的链接压缩成较短的链接。并通过跳转的方式,将用户请求由短链接重定向到长链接上去。短链接主要用在诸如微博...

    SexySix 评论0 收藏0

发表评论

0条评论

dayday_up

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<