Posh:数据感知外壳

2021-08-09 10:18:37

这是“壳牌的未来”系列文章的第四篇。这里是第 1 部分、第 2 部分和第 3 部分的链接。这些每周论文评论可以每周发送到您的收件箱,或者您可以订阅新的 Atom 提要。在接下来的几周内,我将阅读 Usenix ATC 和 OSDI 的论文 - 与往常一样,请随时在 Twitter 上提供有关阅读论文的反馈或建议!本周的论文评论涵盖了 POSH,这是一个能够在未修改的情况下实现显着加速的系统 需要对 shell 脚本进行较少的更改以使其与 POSH 兼容,从而简化了采用。执行大量 IO 的 shell 脚本——POSH 的有趣用例是日志分析或大型软件项目的 git 工作流本文分析了 Chromium 的 git 工作流。 .特别是,POSH 在使用分布式文件系统(如网络文件系统 NFS)的环境中大放异彩,它允许您将远程磁盘“挂载”到您的计算机,然后将 RPC 调用发送到远程服务器以执行文件访问。我强烈推荐操作系统中对 NFS 的这个惊人的(并且免费的!)描述:三个简单的部分。整本书可在此处免费在线获取。 (NFS) 挂载 - 我在侧边栏中包含了一个 NFS 概述的链接(或者,如果您使用的是移动设备,您可以单击数字“4”来显示它)。 POSH 通过最小化使用网络存储的脚本中的数据传输来实现加速。为了最小化数据传输,POSH 可以执行脚本的一部分,在远程机器上的进程中读取或写入远程文件。例如,考虑存储在远程机器上的文件的 grep。在这种情况下,客户端是指由用户启动脚本的计算机。计算机尝试 grep 文件,shell 将通过网络将整个文件传输到客户端节点,然后在客户端过滤文件。相比之下,POSH 可以在远程存储服务器上执行 grep,并且只将过滤后的输出传输回客户端,从而显着降低网络流量。为了决定远程执行脚本的哪些部分,POSH 生成了 shell 脚本执行的图形表示——图中的节点是命令,而边代表命令之间的数据流。将 shell 脚本正确地转换为这种图形表示是一项细微但关键的功能。为方便起见,POSH 利用了一种能够描述给定命令的参数、输入和输出(以及许多重要的配置选项)的注释语言。 POSH 和上周论文评论中描述的系统 PaSh 的相似之处在于它们都旨在加速 shell 脚本的执行,而无需修改原始脚本。此外,它们都在其实现中利用了 shell 命令的注释。尽管这两个项目在某些方面相似,但 PaSh 和 POSH 侧重于不同的用例——PaSH 侧重于并行化机器本地的“平凡可并行化”计算,而 POSH 侧重于并行化跨远程机器执行大量 IO 的脚本。这两个项目都是与外壳现代化相关的令人兴奋(且影响很大)的研究线程的一部分,我期待着从两个团队中看到更多!这篇论文有两个贡献。第一个是描述 shell 命令的注释语言。这些命令规范用于将脚本转换为图形表示——脚本执行的不同步骤是节点,而这些节点之间的数据流是边。第二个贡献是一个调度算法,它决定脚本中的步骤应该如何执行,考虑到脚本图形表示中的依赖关系以及一个步骤与远程存储的交互。在我们深入研究这两个贡献的细节之前,首先了解 POSH 的三个高级组件是有帮助的:

注释接口:如上所述,注释语言允许将 shell 脚本正确转换为图形表示。解析器和调度器:解析器使用上述注释来生成 shell 脚本的图形表示。调度程序使用此图形表示将步骤的执行分配给称为代理服务器的远程或本地节点。调度过程的内部细节将在本文回顾中详细介绍。执行引擎:一旦调度程序将工作分配给代理服务器,该工作将被执行,结果将通过网络传输回客户端节点。 POSH 使用其 shell 注释语言来描述任何给定 shell 命令执行的约束。然后使用这些注释将 shell 脚本转换为正确的图形表示,在安排时,它将实现 POSH 最小化网络流量的目标。该论文概述了 POSH(和注释语言)必须回答以实现系统目标的三个问题:哪些命令可以在远程节点(称为代理服务器)上执行?:这对于确定哪些必须在本地运行,哪些可以运行很重要在远程代理服务器上。在提供的脚本中是否有任何命令“过滤他们的输入”?:知道一个命令是否过滤了它的输入对于确定它是否应该与其他命令一起远程执行很有用。该论文提供了在同一远程代理服务器上执行 cat 后跟 grep 的示例 - 因为“cat 通常产生与输入相同数量的输出,但 grep 通常过滤其输入,POSH 还必须卸载 grep”以最小化网络交通。

Can a command be parallelized?:为了实现最佳调度,POSH 应该尽可能地并行化命令。如果没有注释语言,系统可能没有做出调度决策所需的信息。一个激励示例是 cat file1 file2 file3 - 注释语言定义 cat 的输入是“可拆分的”,这意味着可能在不同的机器上并行运行三个命令 cat file、cat file2 和 cat file3。我想注意注释语言的两个重要组成部分,对于理解本文的其余部分很重要。这篇论文提供了关于注释语言的大量细节,如果您感兴趣的话,我强烈建议您参考原始论文! .首先,可以为每个命令和每个参数定义注释——这种灵活性很重要,因为命令的不同参数可以改变其行为和参数。其次,可以键入命令的输入/输出,并定义其行为。例如,注释语言可以指示命令的可并行性。例如,cat 使用 splittable 进行注释,以表明它具有潜在的可并行性。或者命令是否依赖于当前目录 例如 git add 依赖于当前目录。 .定义命令的这些属性允许解析器和调度器回答上述三个问题。下一节将介绍如何调度和执行通过将 shell 脚本传递给 POSH 的解析器而生成的 shell 脚本的图形表示。如上所述,每个 shell 脚本都通过 POSH 解析器来生成图形表示。然后基于解决调度约束并最小化网络传输的两步过程调度图形表示中的节点以执行。调度的第一步,解决约束,确定图中的任何节点是否必须在给定的远程机器上运行(如果是,是哪个)。出于多种原因创建调度约束——一个示例约束是针对访问远程文件的命令。为了避免通过网络传输整个文件,必须在远程节点上调度该命令。第二步,最小化数据传输,如果在第一步中没有分配命令,则将命令分配给远程机器。对于这个作业,POSH 使用了一些图论,并使用源、汇和路径来实现一个算法。引用 Steve Yegge 的话,“图,就像,真的非常重要。” .源是“读取的文件”,接收器是“写入的输出文件”,路径连接它们。为了分配节点,POSH 遍历每个源节点,检查路径中的接收器和源节点是否已经分配给同一台机器——如果已经分配给同一台机器,则将路径上的所有中间节点也分配给该机器!如果接收器不在同一台机器上,“调度程序必须找到应该发生跨位置数据传输的边缘:为了最小化数据传输,这应该是数据流最少的边缘。”这篇论文描述了一组启发式算法(在 Rust 中实现!)用于找到路径中的最小切割边缘。找到这条边后,未分配的节点被安排在源或接收器被调度的机器上运行,“取决于节点是在最小切割边之前还是之后”。 POSH 是根据执行多个应用程序所需的时间进行评估的。这篇论文评论集中在两个特定的应用程序上:分布式日志分析和 Chromium 的 git 工作流。实验配置涉及使用云到云设置(客户端和机器在云中)或大学到云设置(POSH 客户端位于斯坦福)。云到云设置具有更高的带宽和更低的 RTT,有助于证明即使使用更强大的网络,POSH 也能够实现加速。

这些实验中的基准性能测量来自使用 NFS 而不是 POSH 来执行每个应用程序。仅 NFS 设置模拟应用程序将执行 IO 密集型工作负载,但无法并行化它们(也无法限制网络开销)的情况。对于分布式日志分析(包括在 15GB 日志转储中搜索 IP 地址),POSH 发现在两个实验设置中跨多个 NFS 挂载并行化的加速,尽管 POSH 看到在大学到云设置中的加速更显着比在云到云设置中(前者提高 12.7 倍,后者提高 2 倍)。对于 git 工作流实验,通过恢复执行 git 操作(如 git status、git add 和 git commit),然后从(相当大的)Chromium 开源项目重新提交 20 个提交 - 如此大项目上的 git 命令会产生许多元数据调用(例如,确定文件是否已更改)。 POSH 在这个实验中大放异彩,在云到云环境中实现了 10-15 倍的延迟改进。这个应用程序似乎非常有用 - 过去,我读过 Facebook 为扩展 Mercurial 所做的努力。 POSH 是一种新颖的系统,用于通过执行“接近数据”的工作来并行化 IO 密集型 shell 脚本。该论文是一项激动人心的研究线索的一个组成部分,它可能会显着改善用户体验——鉴于来自不同背景的技术人员每天都在使用 shell,这些改进将产生巨大影响。下周我将继续这个系列,进入 Usenix ATC 和 OSDI 的论文。与往常一样,请随时在 Twitter 上提供有关要阅读的论文的反馈或建议。直到下一次!