安裝其他核心和程式庫 - Amazon EMR

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

安裝其他核心和程式庫

當您 JupyterHub 在 Amazon 上創建群集時EMR,默認的 Python 3 內核為 Jupyter 以及 Sparkmagic 的 PySpark 和星火內核都安裝在碼頭容器上。您可以安裝額外的核心。您也可以安裝其他程式庫和套件,然後將其匯入適當的 shell。

安裝核心

核心安裝在 Docker 容器中。要達成這件事最簡單的方法,就是以安裝命令來建立 bash 指令碼並將它儲存到主節點,然後使用 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

使用程式庫並安裝其他程式庫

Amazon JupyterHub 上已預先安裝一組適用於 Python 3 的核心機器學習和資料科學程式庫EMR。您可以使用 sudo docker exec jupyterhub bash -c "conda list" sudo docker exec jupyterhub bash -c "pip freeze"

如果 Spark 任務需要工作者節點上的程式庫,我們建議您使用引導操作來執行程式碼,以在建立叢集時安裝程式庫。叢集建立過程中,在所有叢集節點上執行的引導操作可簡化安裝。在叢集開始執行後,如果您在核心/工作者節點上安裝程式庫,該操作將更顯複雜。我們在此章節提供一個範例的 Python 計畫,說明如何安裝這些程式庫。

在此章節中顯示的引導操作和 Python 計畫範例,會在所有節點上使用儲存至 Amazon S3 的 bash 程式碼以安裝該程式庫。

下列範例中參考的指令碼使用 pip 安裝 paramiko、nltk、scipy、scikit-learn 以及適用於 Python 3 核心的 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 程式中使用此物件。

若要指定啟動程序動作,當您使用 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.36.2 \ --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 主控台,然後從側邊導覽選取「切換至舊主控台」。如需有關切換至舊主控台時預期情況的詳細資訊,請參閱使用舊主控台

  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 (名稱) 中,輸入易記的名稱。對於指令碼位置,請在 Amazon S3 中輸入指令碼的位置 (我們使用的範例是 s3://mybucket/ install-my-jupyter-libraries .sh)。讓 Optional arguments (選擇性引數) 留白,然後選擇 Add (新增)

  7. 為您的叢集指定其他設定,然後選擇 Next (下一步)

  8. 指定安全性設定,然後選擇 Create cluster (建立叢集)

範例 在執行中叢集的核心節點上安裝程式庫

在 Jupyter 中的主節點上安裝程式庫之後,您可以在執行中的核心節點上以各種方式安裝程式庫。以下範例顯示了本機電腦上執行的已撰寫 Python 計畫。當您在本機執行 Python 程式時,它會使用AWS-RunShellScript的 AWS Systems Manager 來執行範例指令碼 (在本節前面所示),該指令碼會在叢集的核心節點上安裝程式庫。

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()