Engineer's Codex 是一份解释现实世界软件工程的时事通讯。
元的 XFaaS 是他们的无服务器平台,“每天在分布于数十个数据中心区域的超过 100,000 台服务器上处理数万亿次函数调用。”
XFaaS 是 Meta 的公共函数即服务 (FaaS) 选项的内部版本,例如 AWS Lambda、Google Cloud Functions 和 Azure Functions。
我有幸能早点看到 报纸 他们写了关于它的文章。
计算机科学家在命名方面并不是最有创意的,因为今年有两篇论文介绍了“XFaaS”。 一个是 Meta 提出的,另一个是 IISC 班加罗尔科学家提出的。
两者是完全不同的系统,所以如果你谷歌“XFaaS”,就知道这篇论文正在讨论 Meta 的系统版本。
在本文中,我首先为那些想要快速总结的人提供高层次的要点和经验教训。 (预计阅读时间:3分钟)
然后,我为那些想要了解 XFaaS 背后架构的人做了更详细的论文演练。 (预计阅读时间:5分钟)
-
论文的一个要点是,可以通过软件优化硬件使用,以提高无服务器性能。
-
Meta 认识到无服务器功能启动开销的浪费,并旨在模仿 通用工作者,即任何工作者都可以立即执行任何功能,而无需启动开销。
-
XFaaS 是 仅用于非面向用户的功能。 无服务器函数具有太多的可变延迟,无法一致地用于面向用户的函数。
-
XFaaS 的客户端以高度尖峰的方式提交函数调用。 高峰需求高出4.3倍 远高于非高峰需求。
-
他们展示的一个负载示例是 15 分钟内提交到 XFaaS 的 2000 万次函数调用。
-
Meta 发现,即使是尖峰函数也有模式,他们利用这些模式使尖峰函数在工作负载上更加可预测。
-
XFaaS实现了日均CPU利用率66%, 远好于行业平均水平。
它有效地 使用时间(通过延迟函数)和空间(通过将其发送到负载较少的数据中心)来分散负载。
Meta 正在继续转变,因为他们的许多功能都安排在非高峰时段,这样负载和成本更容易预测。
由于它是内部云,Meta 能够执行许多独特的优化,例如在同一进程中运行不同用户的多个功能。
大多数函数的执行时间不到一秒,但并非全部。
友好的插头: 瑞典测验 汇集了 450 多个软件工程和系统设计问题,涵盖数据库、身份验证、缓存等。
它们是由 Google、Meta、Apple 等公司的工程师创建的。
它帮助我的许多同事(包括我自己)在面试中通过了“软件琐事问题”,并在工作中感到更加自信。
问题:冷启动时间过长。
-
如果容器关闭得太早,则必须为下一次调用再次初始化整个容器。
-
如果容器关闭得太晚,它就会闲置,浪费宝贵的计算资源。
-
解决方案:XFaaS使用即时编译等方法来近似每个worker可以立即执行任何函数。
问题:负载变化较大。
-
由于过度配置而导致额外的硬件成本,或者在配置不足时导致系统速度变慢
-
解决方案:XFaaS 将延迟容忍功能的运行推迟到非高峰时间,并在全球数据中心区域之间分发功能调用。
问题:下游服务过载。
-
示例:有一次,来自非面向用户的功能的调用激增导致面向用户的在线服务中断。
-
解决方案:XFaaS采用类似于TCP拥塞控制的机制来规范功能的执行。
-
公共云 FaaS 将函数执行限制在单个数据中心区域,而 XFaaS 可以在全局范围内调度函数调用,从而实现更好的负载平衡。
可以使公共云受益的 XFaaS 技术包括:
-
允许调用者指定函数执行开始时间。
-
使职能所有者能够设置有关完成期限的服务级别目标 (SLO)。 (低 SLO 可以延迟更长时间。)
-
允许职能所有者为职能分配关键级别。
虽然公共云可能无法像 XFaaS 那样在同一流程中运行不同用户的功能,但大型云客户可以在其虚拟私有云中采用 XFaaS 方法。
少数 Meta 团队消耗了 XFaaS 容量的很大一部分。 公共云中类似的大客户也可能会从 XFaaS 的策略中受益。
这是 XFaaS 详细概述的开始。 预计阅读时间:5 分钟
如前所述,XFaaS 可以处理非常尖的负载。 在需求高峰时,仅一个功能每分钟就可以接收 130 万次调用。
一个关键的见解是 大多数 XFaaS 功能都是由自动化工作流程触发的,延迟是可以接受的。 同样,这允许 XFaaS 跨时间(通过延迟函数)和空间(通过将其发送到负载较少的数据中心)来平衡负载。
XFaaS 支持 PHP、Python、Erlang、Haskell 的运行时以及任何语言的基于容器的通用运行时。
函数有一些开发者可以设置的属性,例如函数名称、参数、运行时、关键性、执行开始时间、执行完成截止时间、资源配额、并发限制和重试策略。 执行完成期限的范围可以从几秒到 24 小时不等。
最后,XFaaS 不同地区的硬件容量不同,因此负载平衡必须考虑到这一点。
Meta 在 XFaaS 上有三种类型的工作负载: 队列触发函数, 事件触发函数 (来自数据仓库和数据流系统中的数据更改事件),以及 定时器触发函数 (按预设时间自动触发)。
XFaaS 用于非面向用户的功能,例如异步推荐系统、日志记录、生产力机器人、通知等。
客户端通过向提交者发送请求来发起函数调用,提交者在将请求传递到 QueueLB(队列负载均衡器)之前应用速率限制。
QueueLB 将函数调用定向到 DurableQ 进行存储,直至完成。
调度程序定期将这些调用移至其 FuncBuffer(内存中函数缓冲区),并按关键性、截止时间和配额对它们进行排序。
准备执行的调用转移到 RunQ,然后 WorkerLB(工作负载均衡器)将它们分派给合适的工作人员。
提交者、QueueLB、调度程序和 WorkerLB 都是无状态的、未分片的,并且在没有指定领导者的情况下进行复制,因此它们的副本扮演着平等的角色。
DurableQ 是有状态的,并具有分片、高度可用的数据库。
只需添加更多副本即可轻松扩展无状态组件。 如果无状态组件发生故障,它的工作可以由对等组件接管。
中央控制器与功能执行路径分开。 他们 不断优化系统 通过更新关键配置参数,这些参数由关键路径组件(例如工作程序和调度程序)使用。
这些配置缓存在组件本身中,因此如果中央控制器发生故障,系统仍能正常运行(但无法重新配置)。
这允许中央控制器停机数十分钟。 这是 Meta 如何在该系统中构建弹性的一个例子。
为了安全或性能而需要强隔离的功能被分配到不同的命名空间,每个命名空间使用不同的工作池来实现物理隔离。
由于私有云内的信任、强制同行评审和现有的安全措施,多个功能可以在单个 Linux 进程中运行。 数据只能从较低的分类级别流向较高的分类级别。
客户端向提交者发送调用。 提交者通过批量调用并将其作为一项操作写入 DurableQ 来提高效率。
提交者通过分布式键值存储管理大型参数存储,并具有内置的速率限制策略。 为了管理客户提交率的变化,区域为常规客户和高频客户提供了两个提交者集。
XFaaS 主动监控高频客户端,需要人工干预来进行限制或服务级别目标 (SLO) 调整。
然后提交者将函数调用发送到 QueueLB。 这 配置器 由于 DurableQ 硬件容量不同,(配置管理系统中央控制器)向 QueueLB 提供路由策略,以平衡不同区域的负载。
对 DurableQ 的调用使用 UUID 进行分片以实现平均分配。 每个 DurableQ 按调用者设置的计划执行时间对函数调用进行分类和存储。
调度程序不断查询 DurableQ 来查找到期的存储函数调用。 当 DurableQ 将函数调用移交给调度程序时,除非执行失败,否则它是该调度程序独占的。
调度程序与 DurableQ 通信:
-
发送 ACK 消息表示执行成功。 然后该函数调用将从 DurableQ 中永久删除。
-
NACK 表示尝试失败。 该函数调用在 DurableQ 中再次可供另一个调度程序处理。
调度程序的主要作用是根据函数调用的重要性、截止日期和容量配额来确定函数调用的优先级。
它从 DurableQ 中获取函数调用,将它们合并到 FuncBuffer 中(按重要性排序,然后是执行截止日期),然后将它们安排在 RunQ 中执行。 FuncBuffers 和 RunQ 都是内存数据结构。
为了管理高效执行并防止系统滞后,RunQ 控制函数调用的流程。 该系统还确保负载平衡,全球流量指挥器(中央控制器)根据需求和容量引导跨区域的功能调用流量,全面优化工作人员利用率。
调度程序中的 RunQ 将函数发送到 WorkerLB(工作负载均衡器),WorkerLB 具有由工作池中的工作线程运行的函数。
在XFaaS系统中,使用相同编程语言的功能是隔离的,具有专用的运行时和工作池。
该系统的设计旨在允许任何工作人员立即执行功能,而不会出现任何初始延迟。 XFaaS 维护始终活跃的运行时,并在本地 SSD 上保持函数代码更新。
XFaaS 引入了协作式 JIT 编译,定期将功能代码捆绑并推送给工作人员。 由于代码经常更新,这是必要的。
JIT 编译分为三个执行阶段:
-
一些工作人员测试新代码。
-
2%的工人进一步测试代码; 有些执行 JIT 编译的分析。
-
JIT 编译在接收函数调用之前完成,从而消除了延迟。
通过协作 JIT 编译,工作人员在功能代码更新后仅 3 分钟即可达到每秒最大请求数,而没有 JIT 编译的情况下需要 21 分钟。
内存限制使得存储每个函数的 JIT 代码变得不可行。
局部性优化器(中央控制器)将功能和工作人员分组,确保占用大量内存的功能是分布式的。
使用位置组可将内存消耗减少 11-12%,并允许工作人员高效、一致地利用内存。
-
功能配额:每个函数都有一个配额,由其所有者设置,定义其每秒的 CPU 周期。 此配额会转换为每秒请求数 (RPS) 速率限制。 中央速率限制器根据函数的 RPS 限制确定是否限制函数调用。
-
功能的动态 RPS 限制:为了防止下游服务负担过重,XFaaS 使用类似 TCP 的协议 AIMD(加法增加,乘法减少)方法 动态调整 RPS 限制。 它可以使用慢启动方法设置并发级别并管理 RPS 变化。
过去的挑战,例如 XFaaS 函数重载 道数据库 导致服务级联故障,凸显了采取这些保障措施的必要性。 现在,XFaaS已经证明了其对下游服务屏蔽的能力,从实际事件中可以看出,其反压机制预先抑制了潜在的过载,保证了服务的稳定性。
这是一篇很棒的论文。 Meta 让我们深入、诚实地了解他们自己的无服务器平台,同时为想要优化自己的无服务器功能使用的开发人员和公司提供清晰的经验教训。 可以在此处找到该论文,但您可能需要机构访问权限才能免费阅读。
此外,业界对使用软件进行硬件优化(例如高效CPU使用)的关注还不够。 虽然谷歌、Facebook 和其他公司都为自己的系统做了这件事,但与软件优化相比,人们对此并没有太多讨论。
同时,如果您对其他现实世界的分布式系统感兴趣, 我还写了有关 Meta 如何通过创建世界上最大的 Memcached 系统来每秒处理数十亿个请求的文章。 在这里阅读。
如果您对本文或系统的任何部分有任何疑问,请在下面发表评论。 我会回答他们。