Meta 如何打造 Threads 的基础设施 [译]
2023 年 7 月 5 日,Meta 推出了的 Twitter 的竞品 Threads,Threads 在前五天内便创下了惊人的记录,吸引了超过 1 亿用户注册。
一个敏捷精益的工程师团队在短短五个月内打造了 Threads。虽然 Threads 项目已经酝酿了一段时间,但直到立项前两天业务团队才最终决定,并通知基础设施团队做好发布准备。这个决定基于 Meta 基础设施团队过去的出色表现和基础设施的成熟度,充满了信心。尽管准备时间极为紧迫,基础设施团队仍然出色地支持了应用的迅猛增长。
数百万用户的流畅注册体验得益于 Meta 超过十年的基础设施和产品开发经验。这并非是专为 Threads 设计的基础设施,而是 Meta 多年来为众多产品所建立。它早已为规模扩张、性能增强和可靠性提升做好了准备,在 Threads 增长速度超乎预料的情况下,它的表现甚至超出了我们的期待。
支撑 Threads 运行需要庞大的基础设施。但在此,我们仅介绍两个关键组件:ZippyDB——我们的分布式 key-value 数据存储系统,以及 Async——我们的异步无服务计算平台。
ZippyDB: 扩展 Threads 的关键数据空间
让我们深入了解存储层的一部分:我们使用了 ZippyDB,这是一个分布式的键/值(key/value)数据库。它被设计为一个全面托管的服务,工程师可以在其基础上构建应用。ZippyDB 完全基于 Meta 的基础设施构建,其托管的键空间(keyspaces)可以轻松地在众多数据中心中进行扩展和灵活部署。我们用 TAO 来支撑社交图谱的存储,TAO 后端连接了 MySQL。因此,在这个系统中,你可以直接找到 Threads 的帖子和回复。ZippyDB 是我们数据堆栈中与 MySQL 对应的键/值部分,用于计数器、动态排名/状态和搜索。
我们能够迅速扩展键空间容量,这得益于两个关键特性:首先,该服务运行在一个共享的硬件资源池中,并与 Meta 的整体容量管理框架相连。新的容量一旦分配给这个服务,相关机器就会自动加入服务的资源池,随后负载均衡器开始工作,把数据迁移到新机器上。一旦新机器加入服务,我们能在几小时内处理成千上万台新机器。这非常有效,但仍不足以应对所有情况,因为从批准新容量到从其他服务中调配资源再到加入 ZippyDB 的整个过程可能需要几天时间。因此,我们还需要能够在更短的时间内应对突发的需求增长。
为了实现即时的资源吸收,我们依赖于服务架构的多租户性(multi-tenancy)和强大的隔离功能。这样,即使是负载需求互补的不同键空间,也可以共享同一底层主机,而不用担心其他工作负载增大时会影响到它们的服务水平。主机资源池中也有一定的余量,用于应对个别键空间未使用的容量和处理灾难恢复事件。我们可以通过调整设置,将这些未使用的资源在键空间之间进行重新分配,利用这些余量,让主机以更高的利用率运行,使得某个键空间能够几乎立即扩展,并在短期内(例如几天)保持这种状态。所有这些都是通过工具和自动化实现的常规配置更改,是日常操作的一部分。
强大的多租户特性与新硬件吸纳能力的结合,使得服务能够在面临突发的大规模新需求时,几乎无缝地实现扩展。
为产品发布优化 ZippyDB
ZippyDB 的分片重组协议使我们能够快速且透明地增加分片因子(即水平扩展因子),无需停机即可适应 ZippyDB 使用案例的扩展,同时确保客户端的完全一致性和正确性。这意味着我们能在新产品发布的关键时刻迅速扩展使用案例,即使其负载激增 100 倍,也不会对发布造成任何中断。
我们通过让客户端对键进行哈希处理,映射到逻辑分片,再将这些映射到物理分片来实现这一过程。当某个案例增长需要重新分片时,我们会配置一组新的物理分片,并通过实时配置更新,无需停机地在客户端中安装新的逻辑到物理分片的映射。利用服务器本身的隐秘访问密钥和重分片工作器中的高效数据迁移逻辑,我们能够原子级别地将逻辑分片从原始映射移动到新映射。所有逻辑分片迁移完毕后,分片重组即告完成,并撤销原有映射。
鉴于扩大使用案例对新产品发布至关重要,我们大力投入资源优化分片重组技术,确保 ZippyDB 的扩展不会阻碍产品的发布。具体来说,我们采用了协调器 - 工作器模型设计分片重组系统,实现了横向可扩展性,使我们能够根据需要加快分片重组速度,如在 Threads 发布时。此外,我们还开发了一套紧急操作工具,以应对突发的案例增长。
这些措施使 ZippyDB 团队能够有效应对 Threads 的快速增长。通常情况下,我们在 ZippyDB 中创建新案例时先从小规模开始,随着需求增长再进行分片重组。这种做法避免了资源过度配置,提高了容量使用效率。随着 Threads 用户量的迅猛增长,我们预见到需要为其准备 100 倍的扩容,因此主动进行了分片重组。在以往开发的自动化工具帮助下,我们成功在 Threads 团队于英国时间午夜释放流量之际完成了分片重组,确保了 Threads 用户体验的流畅性,即便用户群体急剧扩大。
Async:针对 Threads 扩展工作负载的执行调整
Async(亦称为 XFaaS)是一个创新的无服务器功能平台,它能够将计算任务延迟到网络不繁忙的时间段进行,帮助 Meta 的工程师们从构思到实际部署解决方案的时间大大缩短。Async 每天能处理数万亿次的函数调用,运行在超过 10 万台服务器上,并支持多种编程语言,如 HackLang、Python、Haskell 和 Erlang,这些可以在这里找到更多信息。
这个平台让开发者可以不用担心部署、排队、调度、扩展以及灾难恢复等复杂问题,让他们可以专注于开发核心业务。只要将代码部署到 Async,就能自动获得高可扩展性等超大规模运算的特点。除了出色的可扩展性,上传至 Async 的代码还享有执行保障,如可定制的重试次数、交付时间、速率限制和容量管理。
Async 常处理的工作任务是那些不需要即时响应用户操作的任务,这些任务可以在用户操作几秒钟到几小时后进行。Async 在帮助用户迅速构建社交网络方面起到了关键作用,例如在 Threads 应用中,用户可以选择关注他们在 Instagram 上关注的人。例如,当新用户加入 Threads 并选择关注他们在 Instagram 上已关注的人时,通过 Async 以高效的方式处理这一请求,避免了在新用户加入过程中的延迟或不良体验。
为了在五天内为 1 亿用户提供这样的服务,Async 需要巨大的处理能力。而且,当许多名人加入 Threads 时,可能会有数百万用户同时关注,这些关注操作和相应的通知也都是通过 Async 实现的,确保了在面对众多用户时仍能保持高效运行。
尽管通过快速引入 Threads 用户而产生的异步(Async)任务数量远超我们的初步预期,但 Async 系统巧妙地应对了这一挑战,将这些任务有序排队等待执行。具体而言,这些任务是在一定的速度限制下进行的,这不仅确保了我们能及时发送通知,促进人们建立联系,还避免了对接收这些异步任务数据的下游服务造成过载。Async 系统自动调整任务执行速度,以适应自身及相关依赖服务(如社交网络数据库)的处理能力,这一切都无需 Threads 的开发工程师或基础设施工程师手动干预。
当基础设施与企业文化相结合
在短短五个月的技术开发期间,Threads 项目的快速进展充分展示了 Meta 强大的基础设施和工程文化。Meta 的产品依托于一个经历了时间考验的共享基础设施,使得产品团队能够迅速行动,快速扩展成功的产品。这一基础设施高度自动化,确保了工作负荷的自动重新分配、负载平衡和扩展都能平稳、透明地进行,除非是临时增加容量的需要。Meta 的快速发展得益于其工程文化,工程师们拥有强烈的主人翁精神,能够无缝协作,实现宏伟的共同目标,其高效的流程是一般组织几个月才能协调的。例如,我们的 SEV 事件管理文化 在需要迅速协调和行动的关键时刻,为我们提供了正确的视角、关注点和行动方案。总的来说,这些因素共同保证了 Threads 项目的成功启动。