如何在Amazon EMR上引导安装Python模块?

47

我想做一些非常基本的事情,只需要通过EMR控制台启动一个Spark集群,并运行一个依赖于Python包(例如Arrow)的Spark脚本。这样做最直接的方式是什么?

5个回答

56

最直接的方法是创建一个包含安装命令的Bash脚本,将其复制到S3中,并从控制台设置引导操作以指向您的脚本。

以下是我在生产中使用的示例:

s3://mybucket/bootstrap/install_python_modules.sh

#!/bin/bash -xe

# Non-standard and non-Amazon Machine Image Python modules:
sudo pip install -U \
  awscli            \
  boto              \
  ciso8601          \
  ujson             \
  workalendar

sudo yum install -y python-psycopg2

1
这将在 EMR 集群中的一个节点上安装软件包。我该如何确保软件包在所有节点上都被安装? - Aliza
11
这会在所有节点上安装这些软件包。 - noli
4
这个方法不能在Python3中使用。我正在尝试安装Pandas,你有任何新的建议吗? - Evan Zamir
@EvanZamir请检查我的答案,你需要在脚本中使用pip-3.4。https://dev59.com/ElwZ5IYBdhLWcg3wYfdu#51210608 - Jonathan Taws
4
这不遵循通常将要求列在 requirements.txt 文件中的惯例。为了允许本地和远程执行,您应该使用 aws s3 cp 将 requirements.txt 复制到本地文件夹,然后在从 s3 复制要求文件后使用 pip install -y requirements.txt 进行安装。 - Eric Meadows
显示剩余2条评论

11

简而言之,使用pip安装软件包有两种方式,取决于平台。首先,您安装所需的内容,然后就可以运行Spark步骤了。最简单的方法是使用emr-4.0.0和'command-runner.jar':

from boto.emr.step import JarStep
>>> pip_step=JarStep(name="Command Runner",
...             jar="command-runner.jar",
...             action_on_failure="CONTINUE",
...             step_args=['sudo','pip','install','arrow']
... )
>>> spark_step=JarStep(name="Spark with Command Runner",
...                    jar="command-runner.jar",
...                    step_args=["spark-submit","/usr/lib/spark/examples/src/main/python/pi.py"]
...                    action_on_failure="CONTINUE"
)
>>> step_list=conn.add_jobflow_steps(emr.jobflowid, [pip_step,spark_step])

在2.x和3.x版本中,您可以类似地使用script-runner.jar,只需指定完整的URI scriptrunner即可。

编辑: 抱歉,我没有看到您想要通过控制台完成此操作。您也可以在控制台中添加相同的步骤。第一步是使用与上面相同的参数的“Customer JAR”。第二步是一个Spark步骤。希望这有所帮助!


2
conn 是从哪里来的? - Adam Kurkiewicz
我想知道为什么他们从boto3中删除了JarStep,它看起来比使用具有相同参数的字典更加简洁... - ciurlaro

9

如果您使用的是Python 2(EMR的默认版本)或Python 3,pip install命令可能不同。

正如noli的回答中所建议的那样,您应该创建一个shell脚本,将其上传到S3存储桶,并将其用作启动操作

对于Python 2(在Jupyter Notebook中:用作pyspark内核的默认版本):

#!/bin/bash -xe
sudo pip install your_package

针对Python 3(在Jupyter中:作为Python 3和pyspark3内核的默认设置):

#!/bin/bash -xe
sudo pip-3.4 install your_package

6
如果您使用的是使用 Python 3.4 的特定 EMR,则这个方法可以正常工作。但需要针对每个 EMR 版本进行单独检查。例如,emr-5.21.0 使用 python-3.6,因此您需要将 pip 调整为 pip-3.6,所以这不是一种适用于所有情况的解决方案。 - Eric Meadows
另一个需要注意的是,如果您想要在使用两个版本的pip进行安装时摆脱整个stderr日志,以下内容将有助于您的引导操作shell脚本:sudo sed -i -e 's/$OLD_PIP_VERSION/$PIP_VERSION/g' /usr/bin/pip-3.6,根据指定的版本。 - Eric Meadows
2
sudo pip3 install.. 能够规避版本标记问题吗? - Jonathan Taws
1
sudo pip-3.6 install boto3``` 对我起作用了。 - ohailolcat

3
这篇文章启发了我,但最终我采用了不同的解决方案。 boostrap.sh
#!/bin/bash

sudo python3 -m pip install \
    botocore \
    boto3 \
    ujson \
    warcio \
    beautifulsoup4  \
    lxml

create_emr_cluster.sh

#!/bin/bash

pem_file="~/.ssh/<your pem file>.pem"
bootstrap_path="s3://<path without filename>/"
subnet_id="subnet-<uniuqe subnet id>"
logs_path="s3://<log directory (optional)>/elasticmapreduce/"

aws s3 cp ./bootstrap.sh $bootstrap_path

ID=$(aws emr create-cluster \
--name spark-data-processing \
--use-default-roles \
--release-label emr-5.30.1 \
--instance-count 2 \
--application Name=Spark Name=Hive Name=Ganglia Name=Zeppelin \
--ec2-attributes KeyName=<your pem file>,SubnetId=$subnet_id \
--instance-type m4.large \
--bootstrap-actions Path=${bootstrap_path}bootstrap.sh \
--query ClusterId \
--output text \
--log-uri ${logs_path})

感谢 EricRops 的帮助。


2

对于Python 3 - 创建一个bash脚本:

#!/bin/bash -xe
sudo pip3 install your_package

将其复制到S3,并从控制台设置引导操作以指向您的脚本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接