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

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

安装其他内核和库

当您使用创建一个群集时 JupyterHub 于 Amazon EMR,Jupyter的默认Python3内核,以及 PySpark Sparkmagic的Spark内核安装在Docker容器上。可以安装其他内核。还可以安装其他库和软件包,然后将它们导入相应的 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 Python2 /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 作业需要工作线程节点上的库,建议使用引导操作运行脚本以在创建集群时安装库。集群创建过程中,引导操作将在所有集群节点上运行,这将简化安装。如果于集群运行后在核心/工作线程节点上安装库,则操作更复杂。我们在此部分中提供了示例 Python 程序以演示如何安装这些库。

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

以下示例中引用的脚本使用 pip Python3内核安装paramiko、nltk、scipy、scikit-learn和panda:

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

创建脚本后,请将其上传到 Amazon S3例如, s3://mybucket/install-my-jupyter-libraries.sh。有关更多信息,请参阅 如何将文件和文件夹上传到S3存储桶Amazon Simple Storage Service 控制台用户指南 以便在bootstrap操作或Python程序中使用它。

指定将在使用 AWS 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.31.0 \ --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 控制台:https://console.amazonaws.cn/elasticmapreduce/

  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 程序时,此程序将使用 AWS 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()