安装其它内核和库 - Amazon EMR
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

安装其它内核和库

当创建包含 JupyterHub on Amazon EMR 的集群时,将在 Docker 容器上安装适用于 Jupyter 的默认 Python 3 内核和适用于 Sparkmagic 的 PySpark 和 Spark 内核。可以安装其它内核。还可以安装其它库和软件包,然后将它们导入相应的 shell。

安装内核

内核安装在 Docker 容器中。安装内核最简单的方式是,创建包含安装命令的清除脚本,将脚本保存到主节点,然后使用 sudo docker exec jupyterhub script_name 命令以在 jupyterhub 容器内运行脚本。以下示例脚本安装内核,然后在主节点上安装内核的一些库,以便之后在 Jupyter 中使用内核时可以导出库。

#!/bin/bash # Install Python 2 kernel conda create -n py27 python=2.7 anaconda source /opt/conda/envs/py27/bin/activate apt-get update apt-get install -y gcc /opt/conda/envs/py27/bin/python -m pip install --upgrade ipykernel /opt/conda/envs/py27/bin/python -m ipykernel install # Install libraries for Python 2 /opt/conda/envs/py27/bin/pip install paramiko nltk scipy numpy scikit-learn pandas

要在容器内安装内核和库,请打开至主节点的终端连接,将脚本保存到 /etc/jupyter/install_kernels.sh,然后在主节点命令行上运行以下命令:

sudo docker exec jupyterhub bash /etc/jupyter/install_kernels.sh

使用库和安装其它库

JupyterHub on Amazon EMR 上预安装有适用于 Python 3 的一组核心的机器学习和数据科学库。可以使用 sudo docker exec jupyterhub bash -c "conda list" sudo docker exec jupyterhub bash -c "pip freeze"

如果 Spark 作业需要 Worker 节点上的库,建议使用引导操作运行脚本以在创建集群时安装库。集群创建过程中,引导操作将在所有集群节点上运行,这将简化安装。如果于集群运行后在核心/Worker 节点上安装库,则操作更复杂。我们在此部分中提供了示例 Python 程序以演示如何安装这些库。

此部分中演示的引导操作和 Python 程序示例都使用保存到 Amazon S3 的清除脚本在所有节点上安装库。

以下示例中引用的脚本将通过 pip 安装适用于 Python 3 内核的 paramiko、nltk、scipy、scikit-learn 和 pandas:

#!/bin/bash sudo python3 -m pip install boto3 paramiko nltk scipy scikit-learn pandas

创建脚本后,将其上载到 Amazon S3 中的位置(例如,s3://mybucket/install-my-jupyter-libraries.sh)。有关更多信息,请参阅《Amazon Simple Storage Service 用户指南》中的上传对象,以便可以在引导操作或 Python 程序中使用此操作。

指定将在使用 Amazon CLI 创建集群时在所有节点上安装库的引导操作
  1. 创建与之前的示例类似的脚本并将脚本保存在 Amazon S3 中的位置。我们将使用示例 s3://mybucket/install-my-jupyter-libraries.sh

  2. 创建已安装 JupyterHub 的集群并使用 --bootstrap-actions 选项的 Path 参数指定脚本位置,如以下示例所示:

    注意

    为了便于读取,包含 Linux 行继续符(\)。它们可以通过 Linux 命令删除或使用。对于 Windows,请将它们删除或替换为脱字号(^)。

    aws emr create-cluster --name="MyJupyterHubCluster" --release-label emr-5.36.1 \ --applications Name=JupyterHub --log-uri s3://MyBucket/MyJupyterClusterLogs \ --use-default-roles --instance-type m5.xlarge --instance-count 2 --ec2-attributes KeyName=MyKeyPair \ --bootstrap-actions Path=s3://mybucket/install-my-jupyter-libraries.sh,Name=InstallJupyterLibs
指定将在使用控制台创建集群时在所有节点上安装库的引导操作
  1. 导航到 Amazon EMR 新控制台,然后从侧面导航栏中选择切换到旧控制台。有关切换到旧控制台后预期情况的更多信息,请参阅 Using the old console

  2. 依次选择 Create cluster (创建集群)Go to advanced options (转到高级选项)

  3. 根据应用程序的情况,指定 Software and Steps (软件和步骤)Hardware (硬件) 的设置。

  4. General Cluster Settings (常规集群设置) 屏幕上,展开 Bootstrap Actions (引导操作)

  5. 对于 Add bootstrap action (添加引导操作),选择 Custom action (自定义操作)Configure and add (配置和添加)

  6. 对于 Name (名称),输入一个易于理解的名称。对于 Script location (脚本位置),输入 Amazon S3 中脚本的位置(我们使用的示例为 s3://mybucket/install-my-jupyter-libraries.sh)。保留 Optional arguments (可选参数) 为空,然后选择 Add (添加)

  7. 指定集群的其它设置,然后选择 Next (下一步)

  8. 指定安全设置,然后选择 Create cluster (创建集群)

例 在运行集群的核心节点上安装库

在 Jupyter 内的主节点上安装库之后,可以通过不同的方式将库安装在运行的核心节点上。以下示例显示了编写为在本地计算机上运行的 Python 程序。当在本地运行 Python 程序时,此程序将使用 Amazon Systems Manager 的 AWS-RunShellScript 运行此节中之前所示的示例脚本,从而在集群的核心节点上安装库。

import argparse import time import boto3 def install_libraries_on_core_nodes(cluster_id, script_path, emr_client, ssm_client): """ Copies and runs a shell script on the core nodes in the cluster. :param cluster_id: The ID of the cluster. :param script_path: The path to the script, typically an Amazon S3 object URL. :param emr_client: The Boto3 Amazon EMR client. :param ssm_client: The Boto3 AWS Systems Manager client. """ core_nodes = emr_client.list_instances( ClusterId=cluster_id, InstanceGroupTypes=["CORE"] )["Instances"] core_instance_ids = [node["Ec2InstanceId"] for node in core_nodes] print(f"Found core instances: {core_instance_ids}.") commands = [ # Copy the shell script from Amazon S3 to each node instance. f"aws s3 cp {script_path} /home/hadoop", # Run the shell script to install libraries on each node instance. "bash /home/hadoop/install_libraries.sh", ] for command in commands: print(f"Sending '{command}' to core instances...") command_id = ssm_client.send_command( InstanceIds=core_instance_ids, DocumentName="AWS-RunShellScript", Parameters={"commands": [command]}, TimeoutSeconds=3600, )["Command"]["CommandId"] while True: # Verify the previous step succeeded before running the next step. cmd_result = ssm_client.list_commands(CommandId=command_id)["Commands"][0] if cmd_result["StatusDetails"] == "Success": print(f"Command succeeded.") break elif cmd_result["StatusDetails"] in ["Pending", "InProgress"]: print(f"Command status is {cmd_result['StatusDetails']}, waiting...") time.sleep(10) else: print(f"Command status is {cmd_result['StatusDetails']}, quitting.") raise RuntimeError( f"Command {command} failed to run. " f"Details: {cmd_result['StatusDetails']}" ) def main(): parser = argparse.ArgumentParser() parser.add_argument("cluster_id", help="The ID of the cluster.") parser.add_argument("script_path", help="The path to the script in Amazon S3.") args = parser.parse_args() emr_client = boto3.client("emr") ssm_client = boto3.client("ssm") install_libraries_on_core_nodes( args.cluster_id, args.script_path, emr_client, ssm_client ) if __name__ == "__main__": main()