原文:
从未使用过 NAS 的人。
几个月前,我终于决定给自己建一个 NAS。 促使我这么做的有几个不同的因素:
于是,在命运的安排下,我开始了工作。
硬件
我可能有点沉迷于购买二手硬件。 有鉴于此,再加上我对 抱着 "我能做得更好 "的态度,我当然不会购买昂贵的新硬件。 尽管如此,我也不想买不可靠的东西,所以我最终在 Kijiji 上花50加元1买了一台 HP 705 G3。
它配备了 AMD 通用预 Ryzen 四核 APU、8GB 内存和通用 500GB 旋转硬盘。 它有三个 SATA 端口,比我的需求少。 因此,我又买了一些内存、三个用于 NAS 实际存储部分的 Crucial MX500 1TB SSD 和一个 PCIe SATA 卡,以便插入更多硬盘。
总之,我的全部费用约为 320 加元,包括存储费用。 我觉得还不错吧?
你可能想知道,3 TB 的原始容量是否就是我 NAS 的全部容量。 我的回答是:是的! 我的存储空间并不大,所以我对此并不在意--我甚至从来没有在我的所有设备上装满过 1TB 的容量。 不过,如果我需要更多容量,PCIe SATA 卡上还有几个端口可以使用。 在最坏的情况下,即使这样也不够,我会屈服并购买存储 10TB 或更大容量的真正 NAS 硬盘,将其用作电脑的启动盘。 你总是可以使用更多的固态硬盘。 这也是我选择固态硬盘而非硬盘的原因--每块硬盘的差价约为 10 美元,而且如果有必要,我也无法将这些硬盘用作启动盘。
软件尝试1[失败]
为了追求与 一样的实用性,我一直在寻找类似的软件解决方案,安装后就能正常使用。 我遇到了 iX Systems 的 TrueNAS,它基本上就是这样的软件。 好极了! 我按照说明进行了设置,然后......重启电脑后发现自己其实没有网络。
我现在是滑铁卢大学的学生,住在校园里,结果发现我房间里的以太网插头坏了。 几个月来我一直没有意识到这一点,因为我的所有其他设备(包括台式电脑)都是通过 WiFi 连接到互联网的,它既可靠又快速,所以我从来没觉得要安装以太网。
哦,好吧。 用 WiFi 不就行了吗? 事实证明,TrueNAS 的官方文档中没有任何地方提到 WiFi,TrueNAS 论坛和 Reddit 上的社区线程要么会与你争论你的使用案例无效,要么会告诉你不支持 WiFi,却没有任何证据支持。
很好。 看来,即使支持这个功能,也会很麻烦。 我就不麻烦了。 相反,我使用 USB 网络连接设置了我的 NAS,并向 IT 部门提交了一张修复以太网端口的单子。
作为设置的一部分,我尝试在它上面安装 ,就像在我所有的设备上一样。 由于大学的 WiFi 是与全校学生和教职员工共享的,他们不允许设备通过局域网相互通信。 因此,如果我想让我的设备能够与我的 NAS 通信(或相互通信),我需要以其他方式将它们连接起来,而 是我所知道的最方便的方式。 自从 2021 年在他们公司实习以来,我一直在使用他们的产品,他们从未让我失望过。
由于我使用的是基于 Debian 的 TrueNAS Scale,我本以为只需添加 的 PPA 并用 sudo apt 安装就可以了。 但 iX 因为有太多人在 Linux 系统内乱搞,然后抱怨,所以他们禁用了 shell 中的 apt,并明确表示不支持通过 shell 对系统进行任何修改。
解决这个问题的方法是通过 "图表",它相当于 TrueNAS 的应用程序,而且据我所知,它可以在本地运行某种 集群(? 因此,我执行了启用 的所有步骤,安装了第三方图表软件仓库(),并从一个有大量选项的轻微损坏图形用户界面上安装了 。 不知怎么搞的,我叹了口气,把电脑收了起来,直到以太网正常工作。
又过了几个月,以太网还是坏了。 IT 部门来测试了几次端口,确定问题出在他们那边,说一周左右就能修好,但一周过去了,他们一直没有回复我的邮件。 哦,好吧。
我目前在 FreeBSD 基金会实习,在实习过程中,我了解到可以将 FreeBSD 系统作为网关,让其他通过以太网电缆连接的计算机通过它访问互联网。 我是否可以通过我的工作电脑上网,因为我的工作电脑就在 NAS 的旁边?
是的,是的,我可以。这很容易2。
这样,我的 NAS 终于可以上网了! 我试着用 的 IP 地址登录 NAS,结果......什么都没有。 我看了看 管理面板,NAS 显示为离线。 这可真够烦人的。 我可以从 NAS ping IP 和域名,因此互联网和 DNS 正常工作。 但不是 ...
这时,我意识到我还有一台电脑——FreeBSD "路由器"——可以直接连接 NAS。 于是,我在路由器上输入了 DHCP 服务器给 NAS 的 IP 地址,管理界面就显示出来了。 我登录进去,经过一番挖掘,发现 不知何故已经自动 "毙命",所有安装在它上面的应用程序都不见了。
此时我可以排除故障......但据我所知,我并没有做错任何事,而且如果系统如此脆弱,并出现了我上面提到的所有并发症,我真的不想再处理它了。 TrueNAS必须退出。
软件尝试2[成功]
全套解决方案似乎并不适合我,所以我决定安装自己的操作系统,并将其设置为可行的配置。 现在的想法是安装一个标准的服务器操作系统,设置我的 RAID 系统,然后将某种自托管云存储解决方案指向它。 不幸的是,这无法为我提供硬件监控功能,不过到时候我还是会跨过这座桥的。
操作系统:FreeBSD
由于我仍然觉得很冒险,所以决定使用 FreeBSD 13.2 作为操作系统。 在我目前的使用中,它看起来相当可靠,配置简单,应该对 ZFS(我打算用于存储的文件系统)有很好的支持,而且有非常棒的文档。 你读过 FreeBSD 手册吗? 与 Rust 一书一样,FreeBSD 13.2 也是在线托管和维护的,与 Arch wiki 或我在 Linux 方面看到的任何其他内容相比,它更适合初学者了解 Unix 操作系统。 强烈建议你通读一下。
安装很简单--如果你以前安装过 Debian,就会想起 Debian 的安装程序。 我把操作系统安装在通用旋转硬盘上,因为我并不特别在意操作系统--如果它死了,我就重新安装它。 重要的是数据,数据将存储在一个由 RAID-Z1 vdev 组成的 ZFS 池中,池中有我的三块固态硬盘。
存储:ZFS w/ RAID-Z1
"一个由 RAID-Z1 vdev 组成的 ZFS 池,里面有我的三个固态硬盘",这句话说得太多了,所以要解释一下:
一旦建立了池,我就可以将其分割成卷。 默认情况下,卷不会使用固定的空间,它只是根据需要使用池中的空间,但如果你怀念过去固定大小分区的美好时光,可以为卷设置 "配额"。 我刚刚创建了两个卷,一个用于存放我的所有文件,另一个用于存放 SQL 数据库。
SQL数据库? 关于这一点:
界面:
是一款 PHP+SQL 云存储解决方案--您只需将其安装在 FAMP4协议栈服务器上,它就能为您提供跨设备同步文件、在旅途中轻松访问文件等多种便捷方式。 正是我所需要的!
尽管 极力推动您使用 Docker 容器进行自托管设置,但他们还是提供了在 Linux 裸机上进行设置的说明,这些说明也适用于 FreeBSD 裸机,几乎没有任何改动。 只要在他们告诉你安装 PHP 模块时安装 php82- 软件包,就几乎可以了。
注意 "几乎"。 我照做了,向 提供了 DB 凭据和管理员用户名/密码,结果看到的是白屏。 通过查看 PHP 日志和在 上搜索,发现 FreeBSD 在 PHP 模块方面还有一些未列出的要求。 安装了 php82-mysqli、php82-filter、php82-xsl 和 php82-wddx(根据我的 PHP 版本进行了调整)后,问题解决了。
设置完成后, 就变得轻而易举了。 我进入管理设置,做了一大堆 "推荐 "的额外操作,比如启用缓存、HTTPS 和其他一些操作。 方便的是,它还会链接到所有建议事项的文档页面。 在 HTTPS 方面,由于我只通过 公开我的 NAS,我可以使用 cert 生成 HTTPS 证书,供 使用。 如果你通过网络公开你的 NAS,你可能会想要使用 Let's Encrypt 或类似的软件。 只是我个人觉得在公共互联网上公开 PHP 网络应用程序有点不妥,所以只能使用内部网络。
做完这一切后,只需设置 移动和桌面应用程序进行同步,我就可以开始使用了! 这些应用程序是我选择 而不只是设置 NFS/SMB 服务器的主要原因--我更看重手机中相机照片的自动同步、本地访问不同电脑上的学校作业文件等功能,而不仅仅是在必要时远程访问服务器上的文件。
结论:经过大量的工作、故障排除和敲脑袋,它终于成功了
我很喜欢这个过程! 我一般都很喜欢配置电脑,NAS 在我使用的几个星期里非常实用和可靠,而且它比 销售的任何产品都要便宜很多。 它确实需要大量的人工干预来设置(偶尔还需要更多的干预),所以我不会把它称作 级别的全套解决方案,但我对我得到的东西非常满意。
我会建议你做同样的事情吗? 对我来说是可行的,但我不是系统管理员,这不是备份建议。 如果你觉得使用二手硬件和开源软件来制作自己的解决方案很舒服,那很好! 但是,如果你想要 "有人已经为我想好了一切,我再也不用担心我的数据会消失了 "这样的安心感,而不需要自己费力去想办法的话,也许 等产品值得你花钱去买。
后记:要做的事情
我仍然需要异地备份--NAS 现在就放在我的桌子下面。 目前的想法是购买 B2 或其他产品,并设置增量备份。
我对 FreeBSD 也还没有百分之百的信心,可能会转到 Linux(可能是 NixOS 或 Fedora ,这样我就可以将整个操作系统配置存储在 git repo 中,而且再也不用担心通用旋转硬盘会死机了)。 我应该在我的数据增长太多之前,或者在建立并检查了异地备份的真实性之后再这样做。 不过现在还能用。
最后,一旦 RAID-Z 扩展实现,我希望能够扩展我的阵列,而不需要销毁和重新创建阵列(或者更有可能的是,添加另一个 RAID-Z1 vdev)。
但那是将来的事! 现在,我比以往任何时候都更有信心,心态更平和。 耶!
本文中的所有价格均为加元。↩︎
对于那些在家跟进的用户,我使用了本指南中的网络设置,只是连接了实际生活中的以太网端口,而不是虚拟机的 TUN 设备。 ︎↩︎
我想知道这是否只是在内部作为 RAID-Z0 实现的。 ↩︎
哈哈, 明白了吧,FreeBSD-Apache-MySQL-PHP? 就像 LAMP,但用的是 FreeBSD 而不是 Linux? 显然,这是这种设置的标准名称--不过也有人用 MariaDB 代替 M,用 Perl 代替 P。↩︎
关于搭建NAS大家都有什么不同的思路呢?欢迎留言讨论,和大家分享你的独家知识。
揭秘 ChatGPT 背后的技术栈:OpenAI 如何将 Kubernetes 扩展到了 7500 个节点
作者 | OpenAI
译者 |
策划 | 褚杏娟
在本文中,OpenAI 的工程师团队分享了他们在 集群扩展过程中遇到的各种挑战和解决方案,以及他们取得的性能和效果。
我们已经将 集群扩展到 7500 个节点,为大型模型(如 GPT-3、 CLIP 和 DALL·E)创建了可扩展的基础设施,同时也为快速小规模迭代研究(如 神经语言模型的缩放定律)创建了可扩展的基础设施。
将单个 集群扩展到这种规模很少见,但好处是能够提供一个简单的基础架构,使我们的机器学习研究团队能够更快地推进并扩展,而无需更改代码。
自上次发布关于扩展到 2500 个节点的帖子以来,我们继续扩大基础设施以满足研究人员的需求,在此过程中学到了许多的经验教训。本文总结了这些经验教训,以便 社区里的其他人也能从中受益,并最后会介绍下我们仍然面临的问题,我们也将继续解决这些问题。
我们的工作负载
在深入探讨之前,我们着重描述一下我们的工作负载。我们在 上运行的应用程序和硬件与大家在普通公司遇到的可能相当不同。因此,我们的问题及解决方案可能与你自己的设置匹配,也可能不匹配!
一个大型的机器学习作业跨越许多节点,当它可以访问每个节点上的所有硬件资源时,运行效率最高。这允许 GPU 直接使用 NVLink 进行交叉通信,或者 GPU 使用 直接与 NIC 进行通信。因此,对于我们的许多工作负载,单个 Pod 占用整个节点。任何 NUMA、CPU 或 PCIE 资源争用都不是调度的因素。装箱或碎片化不是常见的问题。我们目前的集群具有完全的二分带宽,因此我们也不考虑机架或网络拓扑。所有这些都意味着,虽然我们有许多节点,但调度程序的负载相对较低。
话虽如此,kube- 的负载是有波动的。一个新的作业可能由许多数百个 Pod 同时创建组成,然后返回到相对较低的流失率。
我们最大的作业运行 MPI,作业中的所有 Pod 都参与一个单一的 MPI 通信器。如果任何一个参与的 Pod 挂掉,整个作业就会停止,需要重新启动。作业会定期进行检查点,当重新启动时,它会从上一个检查点恢复。因此,我们认为 Pod 是半有状态的——被删掉的 Pod 可以被替换并且工作可以继续,但这样做会造成干扰,应该尽量减少发生。
我们并不太依赖 的负载均衡。我们的 HTTPS 流量非常少,不需要进行 A/B 测试、蓝 / 绿或金丝雀部署。Pod 使用 SSH 直接通过 Pod IP 地址与 MPI 进行通信,而不是通过服务端点。服务“发现”是有限的;我们只在作业启动时进行一次查找,查找哪些 Pod 参与 MPI。
大多数作业与某种形式的 Blob 存储进行交互。它们通常会直接从 Blob 存储流式传输一些数据集的分片或检查点,或将其缓存到快速的本地临时磁盘中。我们有一些 ,用于那些需要 POSIX 语义的情况,但 Blob 存储更具可扩展性,而且不需要缓慢的分离 / 附加操作。
最后,我们的工作性质本质上是研究,这意味着工作负载本身是不断变化的。虽然超级计算团队努力提供我们认为达到“生产”质量水平的计算基础架构,但在该集群上运行的应用程序寿命很短,它们的开发人员会快速迭代。因此,随时可能出现新的使用模式,这些模式会挑战我们对趋势和适当权衡的设定。我们需要一个可持续的系统,同时也能让我们在事情发生变化时快速做出响应。
网 络
随着集群内节点和 Pod 数量的增加,我们发现 Flannel 难以满足所需的吞吐量。因此,我们转而使用 Azure VMSS 的本地 Pod 网络技术和相关 CNI 插件来配置 IP。这使我们的 Pod 能够获得主机级别的网络吞吐量。
我们转而使用别名 IP 地址的另一个原因是,在我们最大的集群中,可能会同时使用约 20 万个 IP 地址。在测试了基于路由的 Pod 网络后,我们发现能够使用的路由数明显存在限制。
避免封装会增加底层 SDN 或路由引擎的需求,虽然这使我们的网络设置变得简单。添加 VPN 或隧道可以在不需要任何其他适配器的情况下完成。我们不需要担心由于某部分网络具有较低的 MTU 而导致的分组分段。网络策略和流量监控很简单;没有关于数据包源和目的地的歧义。
我们使用主机上的 标记来跟踪每个 和 Pod 的网络资源使用情况,这使研究人员可以可视化他们的网络使用模式。特别是,由于我们的许多实验具有不同的 和 Pod 内通信模式,因此能够调查任何瓶颈发生的位置通常是非常有意义的。
可以使用 mangle 规则任意标记符合特定条件的数据包。以下是我们用来检测流量是内部流量还是 流量的规则。FORWARD 规则涵盖了来自 Pod 的流量,而 INPUT 和 OUTPUT 规则涵盖了主机上的流量:
iptables -t mangle -A INPUT ! -s 10.0.0.0/8 -m comment --comment "iptables-exporter openai traffic=internet-in"
iptables -t mangle -A FORWARD ! -s 10.0.0.0/8 -m comment --comment "iptables-exporter openai traffic=internet-in"
iptables -t mangle -A OUTPUT ! -d 10.0.0.0/8 -m comment --comment "iptables-exporter openai traffic=internet-out"
iptables -t mangle -A FORWARD ! -d 10.0.0.0/8 -m comment --comment "iptables-exporter openai traffic=internet-out"
一旦标记, 将开始计数以跟踪匹配该规则的字节数和数据包数。你可以使用 本身来查看这些计数器:
% iptables -t mangle -L -v
Chain FORWARD (policy ACCEPT 50M packets, 334G bytes)
pkts bytes target prot opt in out source destination
....
1253K 555M all -- any any anywhere !10.0.0.0/8 /* iptables-exporter openai traffic=internet-out */
1161K 7937M all -- any any !10.0.0.0/8 anywhere /* iptables-exporter openai traffic=internet-in */
我们使用名为 - 的开源 导出器将这些数据追踪到我们的监控系统中。这是一种简单的方法,可以跟踪与各种不同类型的条件匹配的数据包。
我们网络模型中比较独特的一点是,我们完全向研究人员公开节点、Pod 和 Service 网络 CIDR 范围。我们采用集线器和分支的网络模型,并使用本机节点和 Pod CIDR 范围路由该流量。研究人员连接到中心枢纽,然后可以访问任何一个单独的集群(分支)。但是这些集群本身无法相互通信。这确保了集群保持隔离、没有跨集群依赖,可以防止故障隔离中的故障传播。
我们使用一个“NAT”主机来翻译从集群外部传入的服务网络 CIDR 范围的流量。这种设置为我们的研究人员提供了很大的灵活性,他们可以选择各种不同类型的网络配置进行实验。
API 服务器
的 API Server 和 etcd 是保持集群健康运行的关键组件,因此我们特别关注这些系统的压力。我们使用 kube- 提供的 Grafana 仪表板以及额外的内部仪表板。我们发现,将 HTTP 状态码 429(请求太多)和 5xx(服务器错误)的速率作为高级信号警报是有用的。
虽然有些人在 kube 内部运行 API 服务器,但我们一直在集群外运行它们。etcd 和 API 服务器都在它们自己的专用节点上运行。我们的最大集群运行 5 个 API 服务器和 5 个 etcd 节点,以分散负载并尽可能减少发生故障后带来的影响。自从我们在 上一篇博文 中提到的将 事件拆分到它们自己的 etcd 集群中以来,我们没有遇到 etcd 的任何值得注意的问题。API 服务器是无状态的,通常很容易在自我修复的实例组或扩展集中运行。我们尚未尝试构建任何自我修复 etcd 集群的自动化,因为发生事故非常罕见。
API 服务器可能会占用相当多的内存,并且往往会与集群中的节点数量成线性比例。对于我们有 7500 个节点的集群,我们观察到每个 API 服务器使用高达 70GB 的堆内存,因此幸运地是,未来这应该仍然在硬件能力范围之内。
API Servers 受到压力的主要来源之一就是对 的 WATCH。在整个集群中有一些服务,如“kubelet”和“node-”,其中每个节点都是成员。当一个节点被添加或从集群中删除时,这个 WATCH 将被触发。通常,由于每个节点本身都通过 kube-proxy 监视 kubelet 服务,因此这些响应中所需的数量和带宽将是N2非常大,有时会达到 1GB/s 或更高。 1.17 中推出的 大大降低了这种负载,减少达 1000 倍。
总的来说,我们会非常注意随着集群规模增大而增加的 API Server 请求。我们尽量避免任何 与 API Server 交互。在需要每个节点监视更改的情况下,引入缓存服务(例如 Datadog Cluster Agent)作为中介,似乎是避免集群范围瓶颈的良好模式。
随着集群的增长,我们对集群的实际自动伸缩越来越少。但当一次性自动扩展太多时,我们偶尔会遇到问题。当新节点加入集群时会生成大量请求,一次性添加数百个节点可能会超过 API 服务器容量的负荷。稍微平滑一下这个过程,即使只有几秒钟也有助于避免宕机。
时间序列度量与 和 Grafana
我们使用 收集时间序列度量数据,并使用 Grafana 进行图形、仪表板和警报。我们从 kube- 部署开始收集了各种各样的度量数据,并使用了一些良好的仪表板进行可视化。随着节点数量的不断增加,我们开始遇到 收集的度量数据数量过多的问题。尽管 kube- 公开了许多有用的数据,但我们实际上并没有查看所有的度量数据,一些数据也过于细化,无法有效地进行收集、存储和查询。因此,我们使用 规则从被摄入的度量数据中“删掉”一些数据。
有一段时间,我们遇到了 消耗越来越多的内存问题,最终导致容器崩溃并出现 Out-Of-Memory 错误(OOM)。即使为应用程序分配了大量的内存容量,这种情况似乎仍然会发生。更糟糕的是,它在崩溃时会花费很多时间在启动时回放预写日志文件,直到它再次可用。最终,我们发现了这些 OOM 的来源是 Grafana 和 之间的交互,其中 Grafana 使用 /api/v1/series API 查询 {le!=""}(基本上是“给我所有的直方图度量”)。/api/v1/series 的实现在时间和空间上没有限制,对于具有大量结果的查询,这将不断消耗更多的内存和时间。即使请求者已经放弃并关闭了连接,它也会继续增长。对于我们来说,内存永远不够,而 最终会崩溃。因此,我们修补了 ,将此 API 包含在上下文中以强制执行超时,从而完全解决了问题。
虽然 崩溃的次数大大减少,但在我们需要重新启动它的时候,WAL 回放仍然是一个问题。通常需要多个小时来回放所有 WAL 日志,直到 开始收集新的度量数据并提供服务。在 Robust 的帮助下,我们发现将 =24 应用于服务器可以显著提高性能。在 WAL 回放期间, 尝试使用所有核心,并且对于具有大量核心的服务器,争用会降低所有性能。
我们正在探索新的选项来增加我们的监控能力,下面“未解决的问题”部分将对此进行描述。
健康检查
对于如此庞大的集群,我们当然依赖自动化来检测并从集群中移除行为不当的节点。随着时间的推移,我们建立了许多健康检查系统。
被动健康检查
某些健康检查是被动的,总是在所有节点上运行。这些检查监视基本的系统资源,例如网络可达性、坏盘或满盘,或者 GPU 错误。GPU 以许多不同的方式出现问题,但一个容易出现的常见问题是“不可纠正的 ECC 错误”。Nvidia 的数据中心 GPU 管理器(DCGM)工具使查询这个问题和许多其他“Xid”错误变得容易。我们跟踪这些错误的一种方式是通过 dcgm- 将指标收集到我们的监控系统 中。这将出现为 RS 指标,并设置为最近发生的错误代码。此外,NVML 设备查询 API 公开了有关 GPU 的健康和操作的更详细信息。
一旦检测到错误,它们通常可以通过重置 GPU 或系统来修复,但在某些情况下确实需要更换基础 GPU。
另一种健康检查是跟踪来自上游云提供商的维护事件。每个主要的云提供商都公开了一种方式来了解当前 VM 是否需要进行会最终导致中断的、即将发生的维护事件。VM 可能需要重新启动以应用底层的超级管理程序补丁,或者将物理节点替换为其他硬件。
这些被动健康检查在所有节点上不断运行。如果健康检查开始失败,节点将自动划分,因此不会在节点上安排新的 Pod。对于更严重的健康检查失败,我们还将尝试 Pod 驱逐,以要求当前运行的所有 Pod 立即退出。这仍然取决于 Pod 本身,可通过 Pod 故障预算进行配置来决定是否允许此驱逐发生。最终,无论是在所有 Pod 终止之后,还是在 7 天过去之后(我们的服务级别协议的一部分),我们都将强制终止 VM。
活动 GPU 测试
不幸的是,并非所有 GPU 问题都会通过 DCGM 可见的错误代码表现出来。我们建立了自己的测试库,通过对 GPU 进行测试来捕捉其他问题,并确保硬件和驱动程序的行为符合预期。这些测试无法在后台运行 - 它们需要独占 GPU 运行数秒钟或数分钟。
我们首先在节点启动时运行这些测试,使用我们称之为“预检()”的系统。所有节点都会附带一个“预检”污点和标签加入集群。这个污点会阻止普通 Pod 被调度到节点上。我们配置了一个 ,在所有带有此标签的节点上运行预检测试 Pod。测试成功完成后,测试本身将删除污点和标签,然后该节点就可供一般使用。
我们还定期在节点的生命周期中运行这些测试。我们将其作为 CronJob 运行,允许它着陆在集群中的任何可用节点上。哪些节点会被测试到可能有些随机和不受控制,但我们发现随着时间的推移,它提供了足够的覆盖率,并且最小化了协调或干扰。
配额和资源使用
随着集群规模的扩大,研究人员开始发现他们难以获取分配给他们的全部容量。传统的作业调度系统有许多不同的功能,可以公平地在竞争团队之间运行工作,而 没有这些功能。随着时间的推移,我们从这些作业调度系统中汲取灵感,并以 原生的方式构建了几个功能。
团队污点
我们在每个集群中都有一个服务,称为“team--manager”,具有多个功能。它的数据源是一个 ,为在给定集群中具有容量的所有研究团队指定了 (节点选择器、应用的团队标签、分配数量) 元组。它会将当前节点与这些元组进行对比,并使用 /team=: 的污点对适当数量的节点进行标记。
“team--manager”还有一个入站的 webhook 服务,因此在提交每个作业时会根据提交者的团队成员身份应用相应的容忍度。使用污点使我们能够灵活地限制 Pod 调度程序,例如允许较低优先级的 Pod 具有 "any" 容忍度,这样团队可以借用彼此的容量,而无需进行大量协调。
CPU 和 GPU
除了使用集群自动缩放器动态扩展我们基于虚拟机的集群之外,我们还使用它来纠正(删除和重新添加)集群中的不健康成员。我们通过将集群的 "最小值" 设置为零、"最大值" 设置为可用容量来实现这一点。然而,如果 cluster- 发现有空闲节点,它将尝试缩小到只需要的容量。由于多种原因(VM 启动延迟、预分配成本、上面提到的 API 服务器影响),这种空闲缩放并不理想。
因此,我们为 CPU 和 GPU 主机都引入了“球形”部署。这个部署包含一个具有 "最大值" 数量的低优先级 Pod 副本集。这些 Pod 占用节点内的资源,因此自动缩放器不会将它们视为空闲。但由于它们是低优先级的,调度程序可以立即将它们驱逐出去,以腾出空间进行实际工作。(我们选择使用 而不是 ,以避免将 视为节点上的空闲工作负载。)
需要注意的是,我们使用 pod 反亲和性(anti-)来确保 pod 在节点之间均匀分布。 调度器的早期版本存在一个 O(N^2) 的性能问题,与 pod 反亲和性有关。自 1.18 版本以后,这个问题已经得到了纠正。
Gang 调度
我们的实验通常涉及一个或多个 ,每个 操作不同部分的训练任务。对于优化器,研究人员需要在进行任何训练之前调度 的所有成员(因为我们通常使用 MPI 在优化器成员之间协调,而 MPI 对组成员变化很敏感)。
然而再默认情况下, 不一定会优先满足某个 的所有请求。例如,如果两个实验都请求 100%的集群容量,那么 可能只会调度给每个实验需要的一半 Pod,这会导致死锁,使两个实验都无法进行。
我们尝试了一些需要自定义调度程序的方法,但遇到了一些与正常 Pod 调度方式冲突的边缘情况。 1.18 引入了核心 调度程序的插件体系结构,使本地添加此类功能变得更加容易。我们最近选择了 插件作为解决此问题的方法。
未解决的问题
随着 集群规模的扩大,我们仍有许多问题需要解决。其中一些问题包括:
指标
在如今的规模下, 内置的 TSDB 存储引擎很难压缩,并且每次重新启动时需要长时间回放 WAL(预写式日志)。查询还往往会导致“查询处理会加载过多样本”的错误。我们正在迁移到不同的、与 兼容的存储和查询引擎。大家可以期待下我们未来的博客文章,看看它的表现如何!
Pod 网络流量整形
随着集群规模的扩大,每个 Pod 的互联网带宽量被计算了出来。每个人的聚合互联网带宽需求变得非常大,我们的研究人员现在有能力会意外地对互联网上的其他位置施加重大资源压力,例如要下载的数据集和要安装的软件包。
结 论
是一个非常灵活的平台,可以满足我们的研究需求。它具有满足我们所面临的最苛刻工作负载的能力。尽管它仍有许多需要改进的地方,但 OpenAI 的超级计算团队将继续探索 的可扩展性。
作者简介:
本文作者为 OpenAI 员工 Eric Sigler 和 Chess。
原文链接:
*请认真填写需求信息,我们会在24小时内与您取得联系。