购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.1 可选方案及技术选型

发号器作为分布式服务化系统不可或缺的基础设施之一,在保证系统正确运行和高可用上发挥着不可替代的作用,在不同的互联网公司里有不同的实现方式。本节将介绍在发号器中生成唯一ID的思路、方法及其特点。

1.1.1 为什么不用UUID

UUID虽然能够保证ID的唯一性,但是无法满足业务系统需要的很多其他特性,例如:时间粗略有序性、可反解和可制造性。另外,UUID 产生时使用完全的时间数据,性能比较差,并且 UUID 比较长、占用空间大,会间接导致数据库性能下降;更重要的是,UUID 并不具有有序性,会导致B+树索引在写的时候有过多的随机写操作(连续的ID会产生部分顺序写);还有,由于在写的时候不能产生有顺序的 append 操作,而需要进行 insert 操作,将读取整个 B+树节点到内存,在插入这条记录后会将整个节点写回磁盘,这种操作在记录占用空间比较大的情况下,性能下降明显。

1.1.2 基于数据库的实现方案

若当前业务系统的ID使用数据库的自增字段,而自增字段完全依赖于数据库,则在进行数据库移植、扩容、洗数据、分库分表等操作时会带来很多麻烦。

在数据库分库分表时,有一种方案是通过调整自增字段或者数据库sequence的步长来确保跨数据库的ID的唯一性,但这仍然是一种强依赖数据库的解决方案,有诸多限制,并且强依赖数据库类型,我们并不推荐采用这种方案。

随着业务的发展,请求的量级在不断增加,导致数据库的性能瓶颈可能会出现。在这种情况下,有些方案会通过设置数据库sequence或者表自增字段的步长进行水平伸缩,如图1-1所示。在如图1-1所示的方案中有8个服务节点,每个服务节点使用一个sequence功能来产生ID,每个sequence的起始ID是不同的,而且是依次增加的,但步长都是8。在用于防止产生的ID重复时,这种方案实现起来简单,也能达到性能目标,还能水平扩展,但也存在如下问题。

● 服务节点固定,sequence 的步长也固定,将来如果增加了服务节点,则难以再进行水平扩展。

● 仍然依赖于数据库,对数据库会造成压力,因为ID的产生在一些场景下也是高频访问的服务。

● 由于多个sequence是疏散管理的,所以增加了人员维护的成本。

图1-1

1.1.3 Snowflake开源项目

Twitter的Snowflake是一个流行的开源的发号器实现,在互联网公司里得到了广泛应用。然而,Slowflake是通过Scala语言实现的,文档简单,发布模式单一,缺少支持和维护,很难在现实项目中直接使用。

1.1.4 小结

由于上面提到的三种方案都有各自的缺陷,所以我们在本章的后续内容中力图实现一个通用、原创的唯一流水号产生器,基于流行的互联网编程语言Java实现,这也是本章发号器项目的示例实现,被命名为 Vesta。Vesta 具有全局唯一、粗略有序、可反解和可制造等特性,支持三种发布模式:嵌入发布模式、中心服务器发布模式、REST发布模式,可以通过Jar包的形式嵌入到Java开发的任何项目中,也可以通过服务化或者REST服务发布,发布样式灵活多样,使用简单、方便、高效。Vesta还可以根据业务的性能需求,产生最大峰值型和最小粒度型这两种类型的ID,它的实现架构使其具有高性能、高可用和可伸缩等互联网产品需要的质量属性,是一款通用的高性能的发号器产品。 REm1WOvAmczl3w0X96B43P+cm3+/30lgysYJ4jBNsY9kbKTUx7/9mSswpasMATwg

点击中间区域
呼出菜单
上一章
目录
下一章
×