在Amazon EC2上运行Spark
Spark的ec2目录下有一个spark-ec2脚本,可以帮助你在Amazon EC2上启动、管理、关闭Spark集群。该脚本能在EC2集群上自动设置好Spark和HDFS。本文将会详细描述如何利用spark-ec2脚本来启动和关闭集群,以及如何在集群提交作业。当然,首先你必须在Amazon Web Services site上注册一个EC2的账户。
spark-ec2可以管理多个命名集群。你可以用它来启动一个新集群(需要提供集群大小和集群名称),关闭一个已有的集群,或者登陆到一个集群。每一个集群的机器将会被划分到不同的EC2安全组(EC2 security groups)当中,而这些安全组的名字是由集群的名称派生而来。例如,对于一个命名为test的集群,其主节点(master)将被分到一个叫test-master的安全组,而其他从节点(slave)将被分配到test-slaves安全组。spark-ec2脚本会自动根据你提供的集群名称,来创建安全组。你可以在EC2的控制台(Amazon EC2 Console)中使用这些名字。
准备工作
- 首先,你需要创建Amazon EC2 key pair 。这需要登陆Amazon Web Services账号,在AWS控制台(AWS console)上点击侧边栏上的Key Pairs来创建,并下载。同时,你要确保给这私匙文件附上600权限(即:可读可写)以便使用ssh登陆。
- 使用spark-ec2的时候,一定要设置好这两个环境变量,
AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
,并使其指向你的Amazon EC2 access key ID 和 secret access key。这些都可以在AWS主页(AWS homepage)上,点击 Account > Security Credentials > Access Credentials获得。
启动集群
- 切换到你下载的spark的ec2目录下
- 运行命令./spark-ec2 -k <keypair> -i <key-file> -s <num-slaves> launch <cluster-name>,其中<keypair>是你的Amazon EC2 key pair的名字(你创建Amazon EC2 key pair的时候所指定的名字),<key-file>是Amazon EC2 key pair的私钥(private key)文件,<num-slaves>是slave节点个数(至少是1),<cluster-name>是你指定的集群名称。
例如:
bash export AWS_SECRET_ACCESS_KEY=AaBbCcDdEeFGgHhIiJjKkLlMmNnOoPpQqRrSsTtU \
export AWS_ACCESS_KEY_ID=ABCDEFG1234567890123
./spark-ec2 --key-pair=awskey \
--identity-file=awskey.pem \
--region=us-west-1 \
--zone=us-west-1a \
launch my-spark-cluster
- 集群启动完成后,检查一下集群调度器是否启动,同时,你可以在Web UI上查看是否所有的slave节点都正确的展示出来了,Web UI的链接在脚本执行完以后会打印在屏幕上(通常这个链接是 http://<master-hostname>:8080)
你可以运行./spark-ec2 –help 来查看更多的选项。以下是比较重要的一些选项:
- –instance-type=<instance-type> 可以指定EC2机器的实例类型。目前,该脚本只支持64-bit的实例类型。
- –region=<ec2-region>可以指定EC2集群部署于哪个地域,默认地域是 us-east-1。
- –zone=<ec2-zone>可以指定EC2集群实例部署在哪些地区(EC2的可用地区)。指定这个参数时注意,有时候因为在某些地区可能出现容量不够,因此你可能需要在其他地区启动EC2集群。
- –ebs-vol-size=<GB>可以在每个节点上附加一个EBS(弹性可持续存储)卷,并指定其总容量,这些存储时可持久化的,即使集群重启也不会丢失。
- –spot-price=<price> 将启动竞价型实例(Spot Instances)工作节点,这些节点可以按需分配,可竞价,并且可以设定竞价最高价格(以美元计)。
- –spark-version=<version> 可以在集群中预先加载指定版本的spark。<version>可以是一个版本号(如:0.7.3)或者是一个git hash值。默认会使用最新版本的spark。
- –spark-git-repo=<repository url> 可以指定一个自定义的git库,从而下载并部署该git库中特定的spark构建版本。默认使用Apache Github mirror 。如果同时指定了spark版本,那么–spark-version参数值不能使用版本号,而必须是一个git提交对应的git commit hash(如:317e114)。
- 如果启动过程中由于某些原因失败了(如:没有给private key文件设定正确的文件权限),你可以用–resume选项来重启并继续已有集群的部署过程。
在VPC(Amazon Virtual Private Cloud)上启动集群
- 运行 ./spark-ec2 -k <keypair> -i <key-file> -s <num-slaves> –vpc-id=<vpc-id> -subnet-id=<subnet-id> launch <cluster-name>,其中,<keypair>是你的EC2 key pair(之前已经创建的),<key-file>是key pair中的私钥文件,<num-slaves> 是从节点个数(如果你是第一次用,可以先设成1),<vpc-id> 是VPC的名称,<subnet-id> 是你的子网名称,最后<cluster-name>是你的集群名称。
例如:
bash export AWS_SECRET_ACCESS_KEY=AaBbCcDdEeFGgHhIiJjKkLlMmNnOoPpQqRrSsTtU \
export AWS_ACCESS_KEY_ID=ABCDEFG1234567890123
./spark-ec2 --key-pair=awskey \
--identity-file=awskey.pem \
--region=us-west-1 \
--zone=us-west-1a \
--vpc-id=vpc-a28d24c7 \
--subnet-id=subnet-4eb27b39 \
--spark-version=1.1.0 \
launch my-spark-cluster
运行应用
- 转到你下载的spark的ec2目录下
- 执行
./spark-ec2 -k <keypair> -i <key-file> login <cluster-name>
远程登录到你的EC2集群,其中,<keypair>
和<key-file> 的说明见本文上面
(这里只是为了方便说明,你也可以使用EC2的控制台) - 如果需要把代码或数据部署到EC2集群中,你可以在登录后,使用脚本 ~/spark-ec2/copy-dir,并指定一个需要RSYNC同步到所有从节点(slave)上的目录。
- 如果你的应用需要访问一个很大的数据集,最快的方式就是从Amazon S3或者Amazon EBS设备上加载这些数据,然后放到你集群中的HDFS上。spark-ec2脚本已经为你设置好了一个HDFS,其安装目录为/root/ephemeral-hdfs,并且可以使用该目录下的bin/hadoop脚本访问。需要特别注意的是,这个HDFS上的数据,在集群停止或重启后,会被自动删掉。
- 集群中也有可以持久的HDFS,其安装路径为/root/persistent-hdfs,这个HDFS保存的数据即使集群重启也不会丢失。但一般情况下,这个HDFS在每个节点上可使用的空间较少(约为3GB),你可以用spark-ec2的选项–ebs-vol-size来指定每个节点上持久化HDFS所使用的空间大小。
- 最后,如果你的应用出错,你可以看看改应用在slave节点的日志,日志位于调度器工作目录下(/root/spark/work)。当然,你也可以通过web UI(http://<master-hostname>:8080)查看一下集群状态。
配置
你可以编辑每个节点上的/root/spark/conf/spark-env.sh文件来设置Spark配置选项(如:JVM选项参数)。这个文件一旦更改,你必须将其复制到集群中所有节点上。最简单的方式仍然是使用 copy-dir 这个脚本。首先,编辑主节点(master)上的spark-env.sh文件,然后,运行 ~/spark-ec2/copy-dir /root/spark/conf 将conf目录RSYNC到所有工作节点上。
configuration guide 这一边文档说明了有哪些可用的选项配置。
终止集群
请注意,如果EC2节点被关闭后,是没有办法恢复其数据的!所以,请务必确保在关闭节点之前,将所有重要的数据复制出来,备份好。
- 切换到spark下的ec2目录
- 运行命令 ./spark-ec2 destroy <cluster-name>
暂停和重启集群
spark-ec2脚本同样支持暂停集群。这种情况下,集群实例所使用的虚拟机都是被停止,但不会销毁,所以虚拟机上临时盘数据都会丢失,但root分区以及持久HDFS(persistent-hdfs)上的数据不会丢失。停止机器实例不会多花EC2周期(意味着不用为机器实例付费),但会持续EBS存储的计费。
- 要停止一个集群,你需要切到ec2目录下,运行 ./spark-ec2 –region=<ec2-region> stop <cluster-name>
- 如果过后又要重启,请运行 ./spark-ec2 -i <key-file> –region=<ec2-region> start <cluster-name>
- 如果需要最终销毁这个集群,并且不再占用EBS存储空间,需要运行 ./spark-ec2 –region=<ec2-region> destroy <cluster-name>(如前一小节所述)
限制
- 对“集群计算”的支持有个限制 – 无法指定一个局部群组。不过,你可以在<cluster-name>-slaves群组中手工启动一些slave节点,然后用 spark-ec2 launch –resume 这个命令将手工启动的节点组成一个集群。
如果你发现一些新的限制或者有什么建议,欢迎贡献(contribute)到社区。
访问S3上的数据
Spark文件接口允许你通过相同的URI格式访问所有在Amazon S3上的数据,当然这些数据格式必须是Hadoop所支持的。你可以通过这种URI格式指定S3路径 s3n://<bucket>/path。在启动Spark集群的时候,可以使用选项–copy-aws-credentials来指定访问S3的AWS证书。更完整的访问S3所需的Hadoop库可以在这里查看 Hadoop S3 page.
另外,访问S3的时候,你不仅可以将单个文件路径作为输入,同时也可以将整个目录路径作为输入。