Redian新闻
>
部署太慢,我们用 Warm Docker 容器将速度提高了 5 倍

部署太慢,我们用 Warm Docker 容器将速度提高了 5 倍

公众号新闻

作者 | Shalabh Chaturvedi
译者 | Sambodhi
策划 | 褚杏娟
背   景

我们使用 Serverless Dagster Cloud 来开发和部署 Dagster 代码,无需设置本地开发环境或任何云基础架构。当提交更改到 GitHub 时,GitHub Action 会直接构建和部署代码到 Dagster Cloud,然后可以在界面上查看并与 Dagster 对象进行交互。Dagster Cloud 可以利用一个远程环境来共享部署,并且可以利用自动创建的临时环境与合作者协作,实现了个人本地开发和共享远程环境的结合。

最初,我们在 Dagster Cloud Serverless 中使用了标准的基于 Docker 的构建流程,但很快发现这个流程会使“编辑 - 部署 - 运行”的循环变得非常缓慢。为了将过程加速,我们实现了一个在 Docker 镜像之外运送代码的系统。本文将描述我们分析的问题、选择的解决方案以及在此过程中做出的各种权衡。

Docker 镜像存在的问题

当我们在 GitHub 上构建 Docker 镜像并将其部署到 Dagster Cloud 时,每次提交需要 3~5 分钟才会在 Dagster UI 中显示。在每次迭代中,无服务器开发人员通常会对代码进行微小更改,但是必须等待 3 分钟以上才能看到该更改的效果,这很快就会变得非常烦人。我们分析了“当你更改一行代码并提交时会发生什么”,并发现以下问题:

你可以看到,有两样东西花了最多的时间:

  • 构建 Docker 镜像(60 ~ 90 多秒)

  • 部署 Docker 容器(90 秒)

让我们分别看一下这两个问题。

构建 Docker 镜像

有一些需要注意的关于构建 Docker 镜像的事情:

  1. Docker 镜像由堆栈中的多个层构成,每层由 Dockerfile 中的一部分命令构建。

  2. 每个层有一个哈希标识。

  3. 上传镜像到注册表时,只上传注册表中不存在的层(由哈希标识确定)。

  4. 在 GitHub 构建机上使用 GitHub Actions 缓存 重新构建镜像会将所有未受影响的层从缓存中拉取到构建机上。请注意,如果你的项目中有大量不会更改的依赖项,它们仍将在构建过程中从缓存中复制到构建机上。

  5. Docker 构建不是确定性的。如果使用完全相同的内容构建两个镜像,可能每次都会产生不同的哈希值。(虽然与本文直接相关性不强,但我们想观察这个意外的结果。作为一个极端情况,请考虑,一个刚构建的大层与已存在于注册表中的层完全相同,但仍然会作为一个新的层被上传。

启动 Docker 容器

关于启动 Docker 容器,我们使用亚马逊云科技 Fargate,需要 45~90 秒的时间来提供和启动一个镜像。它不提供任何镜像缓存。启动一个新的容器会将所有层从注册表下载到已提供的容器中。

其他限制

在 Docker 镜像构建和启动后,我们运行用户的代码来提取元数据,并在 UI 中显示。这是不可避免的,并且可能需要几秒钟、30 秒或更多时间,具体取决于如何计算元数据(例如可能会连接数据库以读取模式)。此代码服务器保持活动状态并服务元数据请求,直到推送代码的新版本,然后启动一个新的容器。

我们有一个关键要求是可重复性:我们需要能够多次重新部署完全相同的代码和环境。使用 Docker 镜像哈希作为代码和环境的标识符非常适合这个要求。

我们的备选方案

下面是我们探索和讨论过的一些备选方案:

  1. 切换到 EC2 以加快容器启动速度。这会增加我们的运营负担,需要我们预先预配、监控和扩展集群。我们仍然会面临 Docker 构建速度慢的问题。

  2. 切换到其他的 Docker 构建系统,例如 AWS CodeBuild。这需要更多的实现工作,并与 GitHub 进行更深入的集成。不确定收益是否值得。

  3. 切换到 AWS Lambda,启动时间更快。Lambda 环境附带其自己的基础镜像,如果需要进行定制则更加困难。它还对执行时间施加了 15 分钟的限制,这将需要为运行时间更长的服务器实施复杂的解决方案。

  4. 通过仅构建和上传更改的代码到相同的服务器,来重复使用长时间运行的代码服务器。这里的挑战是实现打包和运行时机制,以确保可靠和可重复的执行环境。我们研究了各种打包和分发 Python 环境的方法,包括 rsync、poetrynixshivpex我们还考虑使用 EFS 卷以及这些工具来挂载 Python 环境。

做出这个决定的关键因素是因为我们意识到,虽然 Docker 镜像是行业标准,但在只需要同步一个小改变时,传输数百兆字节的镜像似乎是不必要的。考虑 git——它只传输差异,但却产生了完整且一致的代码库。

这让我们倾向于选择方案 4……如果我们能找到一个适合我们大部分工作工具的话。经过一些实验,我们发现 PEX 具有许多特性,非常适合我们的使用情况——在下一节中会详细介绍。

什么是 PEX?

PEX 是 Python 可执行文件的缩写,是一个将 Python 包打包成名为 pex 文件的工具。这些可执行文件包含 Python 包和一些引导代码。例如,我们可以将 dagster 包和其依赖项打包成单个文件,然后运行它:

% pex dagster --python=python3.8 -o dagster.pex% ./dagster.pexPython 3.8.16 (default, Dec  7 2022, 01:24:57)[Clang 14.0.0 (clang-1400.0.29.202)] on darwinType "help", "copyright", "credits" or "license" for more information.(InteractiveConsole)>>> import dagster>>>

将整个环境存储在单个文件中非常方便,可以轻松地将其传输到 S3 中进行存储。PEX 提供了更多功能,不仅仅是“文件中的虚拟环境” - 这里是我们使用的其他功能:

  • 隔离性

在运行时,pex 环境与其他全局包完全隔离。在环境中只有捆绑在 pex 文件中的包。我们将多个 pex 文件一起发送到同一台机器上,而不必担心环境隔离问题。

  • 确定性

使用相同的输入包会生成完全相同的 pex 文件:

$ pex dagster pandas -o out.pex | sha256sume3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  -$ pex dagster pandas -o out.pex | sha256sume3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  -

这让我们可以使用内容寻址来识别这些 pex 文件,从而对实现可重复性更有信心。为了实现可重复性,除了使用 Docker 镜像哈希之外,我们还使用 pex 文件哈希。

  • 组合

多个 pex 文件可以在运行时合并,有效地将多个环境合并为一个环境。

% pex pandas -o pandas.pex% pex dagster -o dagster.pex% PEX_PATH=pandas.pex ./dagster.pexPython 3.8.16 (default, Dec  7 2022, 01:24:57)[Clang 14.0.0 (clang-1400.0.29.202)] on darwinType "help", "copyright", "credits" or "license" for more information.(InteractiveConsole)>>> import pandas>>> import dagster>>>

我们使用这个功能将代码分成两个部分,在运行时合并起来:一个包含所有依赖项的 deps.pex 文件,和一个仅包含用户代码的 source.pex 文件。

  • 跨平台构建

我们在 Serverless Cloud 中使用 Linux python:* -slim 衍生的基础镜像。只要有包的 wheel,pex 工具就可以在任何平台上为 Linux 构建 pex 文件。

快速部署

使用 pex 和 S3 存储 pex 文件,我们构建了一个系统,其中快速路径避免了构建和启动 Docker 镜像的开销。

我们的系统工作方式如下:当你将代码提交到 GitHub 时,GitHub 操作根据你的依赖关系是否与上一次部署不同,执行全量构建或快速构建。我们跟踪在 setup.pyrequirements.txt 中指定的依赖关系集。

对于全量构建,我们将你的项目依赖项构建为 deps.pex 文件,将你的代码构建为 source.pex 文件。这两个文件都会上传到 Dagster Cloud。对于快速构建,我们只构建并上传 source.pex 文件。

在 Dagster Cloud 中,我们可能会重复使用现有容器或为代码服务器提供新的容器。我们将 deps.pexsource.pex 文件下载到此代码服务器上,并在隔离环境中使用它们运行你的代码。我们从不跨用户共享容器,容器上的所有环境都属于同一用户。快速部署的最佳时间和最差时间如下所示:

这里的要点是,在快速路径中——当我们进行快速构建并重用现有容器时——整个过程只需要大约 40 秒,而不是之前的 3 分钟多。我们称这个功能为快速部署,现在已经默认开启了所有新的无服务器注册。

权衡和问题

这种方式可以显著提高部署速度(4~5 倍),但也带来了一些权衡和其他需要调整的因素:

  1. 虽然现在我们可以在一个代码服务器上运行多个环境,并且在代码方面是隔离的,但它们仍然共享相同的 RAM 和 CPU。如果我们将太多的环境放在一个容器中,而一个环境占用了太多的内存,就可能对在同一个容器中运行的其他环境产生不利影响。

  2. Docker 可以在任何操作系统上为 Linux 构建 Python 包,因为在构建过程中目标 Linux 操作系统和 Python 解释器都可用。pex 仅为提供 wheel 的包构建 Linux 的 pex 文件。如果出现问题,我们在构建过程中使用 Docker 容器来处理源分发未来,这一步骤可以移动到单独的共享服务中。

  3. 在构建 Docker 镜像时可以进行深度定制,例如,你可以指定自定义基础镜像而不是默认的 python:*-slim 镜像之一。为了实现功能的平等,我们实现了一种方法,允许用户指定他们自己的基础 Docker 镜像,我们将其用于快速部署。

GitHub 工作流和 PEX

你可能已经注意到,在最初的图表中,Download Docker based action 的操作大约需要 10 秒钟。我们是如何完全消除这个步骤的呢?

我们曾经将 GitHub action 代码打包成 Docker 镜像,并使用 Docker container action。现在,我们将我们的 action 代码打包为 pex 文件,将其检入我们的 action 存储库并直接在 GitHub runner 上运行。这消除了下载和启动 Docker action 镜像所花费的时间,同时仍允许我们打包所有依赖项。

我们做出的另一个小优化是只使用一个 GitHub 工作流作业。在 GitHub 中,每次作业启动需要大约 10 秒钟来准备一个新的 runner。

总   结

将部署时间从超过 3 分钟缩短到 40 秒是一个显著的加速,我们对这个结果非常满意,特别是在测试自己的服务时。使用 pex 使我们能够在 Docker 之上构建一个可重复、一致的环境,我们很高兴能够探索使用 pex-on-docker 组合的其他可能性。

如果有兴趣,可以看 PEX 团另一篇关于使用 Docker 进行部署的博客文章,它描述了如何使用 pex 文件作为中间目标来加速 Docker 镜像构建。

原文链接:

https://dagster.io/blog/fast-deploys-with-pex-and-docker

声明:本文为 InfoQ 翻译,未经许可禁止转载。

点击底部阅读原文访问 InfoQ 官网,获取更多精彩内容!

今日好文推荐

针锋相对!为挑战GPT-4加持的Copilot X,谷歌与拒绝被微软收购的Replit联合发布编码工具

后摩尔定律时代,如何提升云效益的天花板

可悲的现实,大部分技术领导者可能并不称职

百度回应文心一言“套壳”质疑;TikTok在美经历生死时刻;IT外包行业面临最大规模裁员,埃森哲将暴力裁员1.9万人 | Q资讯

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
Harman Kardon Soundsticks III 2.1 Channel Speaker【Locker Room】LOL联赛?篮球全明星?Lockerroom有什么新活?K8s 弃用 Docker!一文介绍 containerd ctr、crictl 使用"𝙇𝙚𝙖𝙙 𝙏𝙝𝙚 𝘾𝙝𝙖𝙧𝙜𝙚"广告#创译挑战Linux 桌面终于迎来了 Docker Desktop 可喜可贺!Jenkins+Docker 实现一键自动化部署项目!步骤齐全,少走坑路硬核观察 #942 Docker Hub 将删除所有没有付钱的开源组织的镜像陌上花开975 Knock Knock~有空吗,我想和你谈个恋爱 | 罗德岛设计学院,善解人意,美剧粉MySQL适合运行在Docker中吗?Docker “认错”卡麦尔的警察和二手店“虚伪” 的 Docker 开始清退开源组织,不付费就删除所有镜像!生活在佛州,你得学好西班牙语月薪 5w+,2023 懂点 K8s/Docker 真的太有必要了!| 极客时间美国普林斯顿大学,校园印象一文搞懂TCP、HTTP、Socket、Socket连接池Docker正在淘汰开源组织,CTO硬刚开发者,网友:想赚钱可以,但沟通方式烂透了【Locker Room】春季了,你不运动一下吗?快来lockerroom 看看吧!膜拜!阿里内部爆款K8s+Docker+Jenkins实战笔记,真的太详细了!2015千人计划变2023千屏突破了互联网大事件:Docker翻脸,不再开源!Docker+Wasm第2个技术预览版发布,新增3个运行时引擎支持通过Yarn工作空间将代码交付速度提高97%靠云原生上岸大厂,这198个Docker、K8s核心知识点总结不容错过!| 极客时间图文并茂,阿里内部爆款K8s+Docker+Jenkins实战笔记因画图太慢,我被设计院劝退了...Docker 翻脸,不再开源!错误使用 GPT-3:成本却降低了40 倍,速度提高了5 倍Docker镜像优化:从1.16GB到22.4MB!孩子看书太慢,怎么才能提升阅读效率?丨欢迎预约!现在不懂K8s/Docker真的不行了!一文吃透K8s/Docker架构与核心技术 | 极客时间Docker“认错”探秘 Docker 容器化技术黑科技 Cgroups红豆年糕彻底告别K8s和Docker Swarm!Ruby On Rails 之父下云后:系统好用又便宜,还清理了几千行代码
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。