这是 fastec2 系列的第2部分。关于 fastec2 的介绍,请参阅 第1部分。
Spot 实例(竞价实例)特别适合长时间运行的任务,因为它们可以节省大量费用,并且你可以在进行大量计算的期间仅使用更昂贵的实例类型。fastec2 包含一些功能,可以使这种用例更加方便。让我们看一个例子。我们将执行以下操作:
- 使用廉价的按需 监控实例 来收集结果(并可选地启动任务)。在本指南中,我们将其称为
od1
(但你可以随意命名) - 创建一个执行所需工作的脚本,并将其所需的任何配置文件放在特定文件夹中。该脚本需要编写为将结果保存到特定文件夹,以便它们得以保存
- 在一个全新的实例中测试脚本是否正常工作
- 在 fastec2 下运行脚本,这将使其在新实例的 tmux session 中启动,所需文件将被复制过去,并且任何生成的结果都将复制回
od1
。 - 在脚本运行时,可以通过连接到其正在运行的 tmux session 或查看正在复制回
od1
的结果来检查其进度 - 完成后,实例将自动终止,我们将在
od1
上查看结果。
让我们看看它是如何工作的以及如何使用的详细信息。在本文的后面,我们还将了解如何使用 fastec2 的 卷 和 快照 功能,以便更轻松地连接到大型数据集。
设置监控实例和脚本
首先,创建一个完成所需任务的脚本。在 fastec2 下运行时,脚本将在一个名为 ~/fastec2
的目录中启动,这个目录还将包含脚本所需的任何额外文件(不在你的 AMI 中的文件),并且会监控文件变化,将变化的文件复制回你的按需实例(在本指南中是 od1
)。这里有一个我们可以用于测试的示例(我们将其称为 myscript.sh
):
#!/usr/bin/env bash
echo starting >> $FE2_DIR/myscript.log
sleep 60
echo done >> $FE2_DIR/myscript.log
运行时,环境变量 FE2_DIR
将被设置为你的脚本和文件所在的目录。记住给你的脚本执行权限。
$ chmod u+x myscript.sh
在新实例上测试时,只需设置 FE2_DIR
并创建该目录,然后查看你的脚本是否运行正常(最好给你的脚本添加一个参数,使其在测试时运行一个快速版本)。
$ export FE2_DIR=~/fastec2/spot2
$ mkdir -p $FE2_DIR
$ ./myscript.sh
使用 fastec2 运行脚本
你需要一台正在运行的计算机,用于收集长时间运行脚本的结果。你不希望为此使用 spot 实例,因为它可能随时被关闭,导致你丢失工作。但这可以是一个廉价的实例类型;如果你的 AWS 账户创建时间不到1年,则可以免费使用 t2.micro
实例。否则,t3.micro
是一个不错的选择——如果一直运行,它的费用大约是每月7美元(加上存储费用)。
要在 fastec2 下运行脚本,你需要提供以下信息:
- 要使用的实例名称(首先使用
launch
创建它) - 你的脚本名称
- 连接到 监控实例 以复制结果的附加参数(
[--myip MYIP] [--user USER] [--keyfile KEYFILE]
)。如果未提供主机,则使用运行fe2
的计算机的 IP 地址。
例如,此命令将在 spot2
上运行 myscript.sh
并将结果复制回 18.188.16.203
$ fe2 launch spot2 base 80 m5.large --spot
$ fe2 script myscript.sh spot2 18.188.162.203
运行上面的 fe2 script
命令后会发生以下情况:
- 如果监控实例上尚不存在,将创建一个名为
~/fastec2/spot2
的目录(它始终是~/fastec2
的一个子目录,并与你连接的实例同名,在本例中为spot2
)。 - 你的脚本被复制到此目录。
- 此目录被复制到 目标实例(在本例中为
spot2
)。 - 在目标实例上创建一个名为
~/fastec2/current
的文件,其中包含此任务的名称(在本例中为“spot2
”)。 - 在目标实例的后台运行
lsyncd
,它将不断地将目标实例上~/fastec2/spot2
目录中的任何新增/更改文件复制到监控实例。 ~/fastec2/spot2/myscript.sh
在 tmux session 中运行。
如果你希望脚本完成后实例终止,请记住在脚本末尾包含 systemctl poweroff
(对于 Ubuntu)或类似的命令。
创建数据卷
上述过程的一个问题是,如果你有大量不同的大型数据集需要处理,你要么需要将所有数据集复制到你要使用的每个 AMI 中(这既昂贵,又意味着每次添加数据集时都需要重新创建该 AMI),要么为每个数据集创建一个新的 AMI(这意味着当你更改配置或添加应用程序时,必须更改所有 AMI)。
一种更简单的方法是将数据集放到一个单独的 卷(即 AWS 磁盘)上。fastec2 可以轻松创建一个卷(格式化为 ext4,这是 Linux 上最常见的文件系统类型)。为此,最简单的方法是使用 fastec2 REPL(关于 REPL 的介绍,请参阅本系列的 第1部分的最后一节),因为我们需要一个可以连接到实例来挂载和格式化新卷的 ssh 对象。例如,要使用实例 od1
创建卷(假设它已在运行):
$ fe2 i
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: inst = e.get_instance('od1')
In [2]: ssh = e.ssh(inst)
In [3]: vol = e.create_volume(ssh, 20)
In [4]: vol
Out[4]: od1 (vol-0bf4a7b9a02d6f942 in-use): 20GB
In [5]: print(ssh.run('ls -l /mnt/fe2_disk'))
total 20
-rw-rw-r-- 1 ubuntu ubuntu 2 Feb 20 14:36 chk
drwx------ 2 ubuntu root 16384 Feb 20 14:36 lost+found
如你所见,新磁盘已挂载到请求的实例上的 /mnt/fe2_disk
目录下,并且新卷已获得与其创建实例相同的名称(od1
)。你现在可以连接到你的实例并将数据集复制到此目录中,完成后,卸载卷(在你的 ssh session 中运行 sudo umount /mnt/fe2_disk
),然后你可以使用 fastec2 分离该卷。如果你的上一个 REPL session 不再打开,你需要先获取你的卷对象,然后才能分离它。
1]: vol = e.get_volume('od1')
In [
2]: vol
In [2]: od1 (vol-0bf4a7b9a02d6f942 in-use): 20GB
Out[
3]: e.detach_volume(vol)
In [
4]: vol
In [4]: od1 (vol-0bf4a7b9a02d6f942 available): 20GB Out[
将来,你可以通过 repl 重新挂载你的卷。
5]: e.mount_volume(ssh, vol) In [
使用快照
卷的一个显著缺点是,你一次只能将一个卷附加到一个实例。这意味着你不能使用卷来启动连接到同一数据集的多个任务。相反,为此目的你应该创建一个 快照。快照是卷的一个模板;从此快照创建的任何卷都将拥有与原始卷相同的数据。但是请注意,快照不会更新卷中添加的任何额外信息——快照中最初包含的数据保持不变。
从卷创建快照(假设你已经有一个卷对象 vol
,如上所述,并且已将其从实例分离):
7]: snap = e.create_snapshot(vol, name="snap1") In [
现在你可以使用此快照创建一个卷,它会自动附加到你的实例。
8]: vol = e.create_volume(ssh, name="vol1", snapshot="snap1") In [
总结
现在我们已经集齐了所有拼图块。在以后的文章中,我们将讨论使用所有这些组件通过 fastec2 运行任务的最佳实践——但这里是流程的快速总结:
- 启动一个实例,并配置所需的软件和设置。
- 如果需要,为数据集创建一个卷,并从中创建快照。
- 停止该实例,并从中创建一个 AMI(可选地,完成后可以终止该实例)。
- 使用廉价的实例类型启动一个 监控实例。
- 为你的长时间运行任务启动一个 spot 实例。
- 从你的快照创建一个卷,并附加到你的 spot 实例。
- 在该实例上运行你的长时间运行任务,并传入你的监控实例的 IP 地址。
- 确保你的长时间运行任务完成后关闭实例,以避免在完成后继续支付实例费用。(你此时可能也想删除从快照创建的卷。)
要运行更多任务,你只需重复最后4个步骤。你可以使用本指南中显示的 API 调用自动化该过程。