12.3 使用亚马逊 Web 服务(AWS)
当你有很多数据、需要进行很多计算的时候,你可能会开始渴求更多的计算资源。亚马逊(aws.amazon.com )允许你按小时租用计算资源。因此,你可以访问到大量的计算资源,而不需要预先购买大量机器(包括管理基础设施的费用)。在这个市场里还有其他的竞争者,但亚马逊是最大的玩家,所以我们在这里简要介绍一下。
亚马逊Web服务 (Amazon Web Services,AWS)是一组庞大的服务。我们只关注其中的Elastic Compute Cluster (EC2 )服务。这个服务提供给你虚拟机和磁盘空间,它们可以很快被分配和释放。
它一共有三种使用模式:保留模式,你可以预先支付,来获得更廉价的按小时的访问;每小时固定率;根据整体计算市场(需求少的时候,费用也低,但需求多的时候,价钱就会提高)提供变化的比率。
如果想测试的话,你可以在免费层级(free tier)中使用一台机器。它允许你试验一下这个系统,熟悉一下接口,等等。然而,这是一台CPU非常慢的机器。所以,我们并不建议用它进行过多的计算。
在整体系统的上层,有几种类型的机器,它们的费用不同;从单核到多核大内存系统,或者甚至是图形处理单元 (Graphical Processing Unit,GPU)。我们之后会看到,你可以得到几台比较廉价的机器,并构建你自己的虚拟集群。你还可以选择Linux或是Windows服务器,其中Linux会便宜一点。在本章里,我们是在Linux上运行我们的例子的,但多数东西在Windows机器上也可以使用。
这些资源可以通过Web界面来进行管理。但也可以在程序中通过脚本来分配虚拟机,设置磁盘,以及所有Web界面所能做的操作。事实上,在Web界面频繁变化的同时(本书里显示的一些图表在本书出版的时候可能已经过时了),编程接口更为稳定。由于服务的引入,整体构架也保持着稳定。
通过传统的用户名/密码就可以访问AWS服务,尽管亚马逊把用户名叫做公钥,把密码叫做私钥。这样做是为了使访问Web接口的用户名和密码分开。事实上,你可以生成很多公/私钥对,并给予它们不同的权限。对于比较大的团队来说(一个能访问所有Web界面的高级用户可以为权限较少的开发者创建密钥),这样做是有益处的。
注意 亚马逊区域
Amazon.com有几个区域。它们与世界的物理区域相对应:美国西海岸、一些亚洲地点、南美区,以及欧洲区。如果你想迁移数据,最好使迁移的出发地和目的地比较靠近。此外,如果你正在处理用户的信息,并且要迁移到另一个管辖区去,那就可能会出现监管问题。在这种情况下,一定要让一个知情律师对欧洲客户数据迁移到美国的影响进行检查;反之亦然。
亚马逊Web服务是一个非常宏大的课题,市面上有各种可以涵盖AWS全部内容的书。本章只是要给你一个整体印象,告诉你AWS有什么,能做什么。基于本书的实践精神,我们先看一些例子,但我们不会穷尽所有可能。
12.3.1 构建你的第一台机器
第一步是到http://aws.amazon.com/ 创建一个账号,这里的步骤跟其他在线服务类似。如果你想要的是比一台低端机器更好的机器,那你需要一张信用卡。在这个例子里,我们会使用一些机器,如果你想在上面运行程序的话,可能要花费一些钱。如果你还没准备掏出信用卡,那应该先阅读本章,了解一下AWS可以提供什么服务。然后,你可以做出更明智的选择,决定是否要进行注册。
一旦注册了AWS并登录,你会看到它的控制台。在这里,你可以看到AWS提供的多种服务:
我们选择并点击EC2 (最左列的第二项,在本书撰写之时,界面是这样显示的;亚马逊经常会进行小修小改,所以你看到的可能有些不同)。我们现在看看EC2的管理控制台,如下图所示:
在右上角,你可以选择你的区域(见美国区域信息框)。注意,你只能看到所选区域的信息。因此,如果选择了错误的区域(或者在不同区域都有机器在运行),这些内容可能不会出现(在同其他程序员的聊天中得知,这似乎是使用EC2 Web管理控制台的一个常见陷阱)。
用EC2的说法,一个正在运行的服务器叫做一个实例 (instance)。所以现在,我们要选择Launch Instance 。现在,遵循典型惯例。选择Amazon Linux 选项(如果你熟悉下列Linux发行版本之一,如Red Hat、SuSe或Ubuntu,可以选择其中之一,但配置将会有些不同)。我们从T1.micr类型的一个实例开始。这是最小的机器,并且是免费的。接受所有默认选项,直到进入下面这个输入密钥对后出现的界面:
我们选择名字awskeys 作为密钥对。然后点击Create & Download your Key Pair 按钮,下载awskeys.pem文件。这是Secure Sheel (SSH ),将使你可以登录云机器。要把文件保存在安全的地方!接受完剩下的默认选项,你的实例就启动了。
现在你需要等待一小会儿,等实例出现。最终,这个实例会用绿色显示,状态为“运行中”。右击并选择Connect 选项,你会知道如何连接。下面是一个标准SSH命令:
ssh -i awskeys.pem ec2-user@ec2-54-244-194-143.us-west-2.compute. amazonaws.com
因此,我们会调用ssh 命令,并把之前下载的密钥文件传进去,作为身份信息(用-i选项)。我们会以用户ec2-user 来登录地址为ec2-54-244-194-143.us-west-2. conompute.amazonaws.com的机器。当然,这个地址跟你的不同。如果在实例中选择另一个版本,用户名也会改变。不管怎样,Web界面会给你正确的信息。
最后,如果是在一个Unix风格的操作系统上(包括Mac OS)运行,你需要通过下面的代码调整它的权限:
chmod 600 awskeys.pem
这个命令会给当前用户设置读/写权限。否则,SSH会给你一个令人厌恶的警告。
现在,你应该可以登录主机了。如果一切顺利,你会看到下面的标语:
这是一个常规的Linux框,你拥有sud权限;如果在前面加上sud,你就可以像高级用户那样运行任何命令。你可以运行更新(update)命令让机器加速。
1. 在亚马逊Linux上安装Python包
如果你要使用另一个分发版本,可以用另一个分发版本的知识来安装Python、NumPy或者其他。在这里,我们采用的是标准亚马逊分发版本。从安装几个基本的Python包开始,如下所示:
sudyum -y install python-devel python-dev python-pip numpy scipy python-matplotlib
要对mahotas进行编译,还需要一个C++编译器:
sudyum -y install gcc-c++
在这个系统里,pip被安装成python-pip 。为方便起见,我们用pip来更新它自己。然后我们用pip安装必要的程序包:
sudpip-python install -U pip sudpip install scikit-learn jug mahotas
在这里,你可以像使用pip那样安装任何其他程序包。
2. 在我们的云主机上运行Jug
现在,我们可以去下载第10章里的数据和代码了。如下所示:
wget FIXME-LET'S-BUILD-A-TAR-GZ-PACKAGE tar xzf chapter10.tar.gz cd chapter10
然后,进行如下操作:
jug execute
它工作得还可以,但我们需要等很长时间才能得到结果。我们的免费级机器(t1.micr类型)是单核的,不是很快。所以我们要升级机器。
我们回到EC2控制台,在运行实例上右击,会出现一个弹窗。我们需要先停掉这个实例。在虚拟机上停止一个实例的运行就如同把它的电源关掉。你可以在任何时候停止你的机器。这时,你不再为它们承担费用(你仍然在使用磁盘空间,这也是有代价的,会分开计算费用)。
一旦你的机器停止了,change instance type 选项就会出现。你可以选择一个更强有力的实例,例如,一个c1.xlarge 实例,它是8核的。这个机器仍然处于关闭状态,你需要重新打开它(这跟重启机器是一样的)。
提示 AWS提供了几种价钱不同的实例类型。由于引入了更强有力的选项,信息经常会不断修正,同时价格也会发生变化,所以在本书里我们没法给你很多具体细节(一般来说会变得更便宜);然而,你可以在亚马逊的网站上找到最新的信息。
我们需要等待实例再次出现。一旦它出来了,右击Connet 获得连接信息。几乎可以肯定,链接信息已经改变了。在你更改实例类型的时候,你的实例会获得一个新分配的地址。
提示 你可以用亚马逊的Elastic IPs功能给实例分配一个固定IP。你可以在EC2控制台的左边看到这个选项。
通过使用8核机器,你可以同时运行8个jug进程,如下面这些代码所示:
jug execute & jug execute & (repeat tget 8 jobs going)
用jug status 可以查看到8个作业是否在运行。完成作业之后(现在应该很快就可以实现),你可以停止机器,并再次降级为t1.micr实例,以节省花销;微型实例是免费的,而这个特大号的机器的价钱是每小时0.58美元(这是2013年4月的价钱——到AWS网站上可以看到最新信息)。
12.3.2 用starcluster自动创建集群
正像你所了解到的,我们可以通过Web界面创建机器,但你很快就会发现,这个操作单调枯燥,而且容易出错。幸运的是,亚马逊有一个API。你可以写脚本自动执行之前讨论过的所有操作。更好的是,其他人已经开发了一些工具。你用AWS要进行的很多过程都可以用这些工具自动化执行。
MIT的一个团队正好开发了这样一个工具,叫做starcluster。它恰好是一个Python包,所以你可以用Python工具把它安装上。
sudpip install starcluster
你可以在亚马逊主机上,或你的本地机器上运行这个代码。这两种方式都行。
我们需要指定我们的集群是什么样的。通过编辑配置文件即可实现。下面的代码生成了一个模板配置文件:
starcluster help
然后,我们选择选项在-/.starcluster/config中生成配置文件。做完之后,我们就可以手动编辑这个文件。
提示 不同的密钥
在使用AWS的时候,有三种密钥。
标准用户名/密码组合,用于登录网站。
SSH密钥系统,它是一个用文件实现的公/私钥系统;通过你的公钥,可以登录远程主机。
AWS访问钥/密钥系统,这只是某种形式的用户名/密码。它允许你在同一个账户下拥有多个用户(包括为每个用户添加不同权限,但本书里不会涵盖这部分高级特性)。
要想查看访问/私钥,我们回到AWS控制台,在右上角点击我们的名字;然后选择Security Credentials 。现在,屏幕的下方应该会出现形如AAKIIT7HHF6IUSN3OCAA 的访问钥,本章将以它为例。
现在编辑配置文件。这是一个标准的.ini文件:一个文本文件,每个部分以方括号和它们的名字开始。选项的格式是name=value 。第一部分是aws inf,你应该把你的密钥粘贴过来:
[aws info] AWS_ACCESS_KEY_ID = AAKIIT7HHF6IUSN3OCAA AWS_SECRET_ACCESS_KEY = <your secret key>
现在来到一个有趣的部分:定义一个集群。starcluster允许你定义任意多个不同的集群。文件的开始有一个叫做smallcluster 的集群。它在cluster smallcluster 部分里定义。把它编辑为:
[cluster mycluster] KEYNAME = mykey CLUSTER_SIZE = 16
它把节点个数从默认的2改为16。我们还可以指定每个节点的实例类型和初始映像(记住,映像是指你使用的是什么操作系统,安装了什么软件)。starcluster有一些预设的映像,但你也可以构建自己的映像。
我们需要创建一个新的ssh 密钥,如下所示:
starcluster createkey mykey -.ssh/mykey.rsa
现在我们已经配置了一个16节点的集群,并设置了密钥。让我们尝试一下。
starcluster start mycluster
这个操作可能需要几分钟,因为它要分配17台新机器。为什么是17台机器,而我们的集群只有16个节点?这是因为会有一个主节点。所有这些节点都使用同一个文件系统,所以在主节点上创建的任何东西,也可以在从属节点上看到。这也意味着我们可以在这些集群上应用Jug。
这些集群可以按照你想要的方式进行使用,但它们都预装了一个作业队列引擎,这种方式对于批处理作业比较理想。它的使用过程很简单。
1. 登录主节点。
2. 在主节点上准备好你的脚本(更好的方式是,在之前就把脚本准备好)。
3. 把作业提交到队列。一个作业可以是任何一个Unix命令。调度程序会寻找空闲节点来运行你的作业。
4. 等待作业结束。
5. 从主节点上读取结果。你现在还可以杀掉所有从属节点,以节约费用。在任何时候都不要忘记你的系统的运行是长期的。否则,这会花费很大(意思是美元和美分)。
我们可以用一个命令登录到主节点上:
starcluster sshmaster mycluster
我们也可以看到我们之前用ssh 命令生成的机器地址,但在使用前面那个命令的时候,地址是什么并不重要,因为starcluster 已经在背后把这些都处理好了。
正如我们前面所说的,starcluster为集群提供了一个批处理排队系统;你可以写脚本执行你的操作,把作业放在队列里,这些作业就会在空闲节点上运行。
在这一点上,你需要在集群上重复安装必要的程序包。如果这是一个真实项目,我们可以创建一个脚本来执行所有这些初始化工作,但由于这是一个教程,你只需要再初始化一次。
我们可以像以前一样使用相同的jugfile.py 系统,但现在,我们会在集群中进行调度,而不是直接在主节点上运行。首先,写一个很简单的脚本:
#!/usr/bin/env bash jug execute jugfile.py
用run-jugfile.sh 调用它,并用chmod +x run-jugfile.sh 赋予它可执行权限:
For c in 'seq 16'; dqsub run-jugfile.sh; done
这会创建16个任务,每个都会运行run-jugfile.sh 脚本调用Jug。你仍然可以使用主节点。需要特别强调的是,你可以在任何时候运行jug status 查看计算状态。事实上,Jug就是在这种环境下开发出来的,所以它在这个环境下工作得很好。
最后,计算结束,可以把所有节点都删掉了。但我们一定要把预期的结果保存在某个地方,并执行下述命令:
starcluster terminate mycluster
注意,终止操作将会销毁文件系统中的内容以及所有运行结果。当然,这个默认设置是可以更改的。你可以让集群把结果写在一个不是由starcluster分配并销毁的而你又可以访问的文件系统里。事实上,这些工具的灵活性非常大。不过这些高级操作并不适合在本章里展开。
starcluster有一个优秀的在线文档,见http://star.mit.edu/cluster/ ,你可以读到关于这个工具的更多信息。我们在这里只看到了一小部分功能,只使用了默认的设置。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论