如何将自定义 JAR 中的函数添加到 EMR 集群?
How to add functions from custom JARs to EMR cluster?
我使用 Spark 和 Livy 在 AWS 上创建了一个 EMR 集群。作为自定义 JAR 步骤,我提交了一个带有一些附加库(例如自定义格式的数据源)的自定义 JAR。但是,当我尝试从 Livy 访问自定义 JAR 中的内容时,它不可用。
我需要做什么才能使自定义内容在环境中可用?
我将此作为答案发布是为了能够接受它 - 由于 Yuval Itzchakov 的评论和关于自定义 Bootstrap 操作的 AWS 文档,我弄明白了。
这就是我所做的:
- 我将我的库 jar(用
sbt assembly
创建的包含所有所需内容的胖 jar)放入 S3 存储桶
创建了一个名为 copylib.sh
的脚本,其中包含以下内容:
#!/bin/bash
mkdir -p /home/hadoop/mylib
aws s3 cp s3://mybucket/mylib.jar /home/hadoop/mylib
创建了以下配置 JSON 并将其放入除 mylib.jar
和 copylib.sh
之外的同一个存储桶中:
[{
"configurations": [{
"classification": "export",
"properties": {
"PYSPARK_PYTHON": "/usr/bin/python3"
}
}],
"classification": "spark-env",
"properties": {}
}, {
"configurations": [{
"classification": "export",
"properties": {
"PYSPARK_PYTHON": "/usr/bin/python3"
}
}],
"classification": "yarn-env",
"properties": {}
},
{
"Classification": "spark-defaults",
"Properties": {
"spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/mylib/mylib.jar",
"spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/mylib/mylib.jar"
}
}
]
PySpark 需要 spark-env
和 yarn-env
的分类才能通过 Livy 在 EMR 上使用 Python3。还有另一个问题:EMR 已经在两个 extraClassPath
中填充了 EMR 正常运行所需的大量库,所以我不得不 运行 一个没有我的库的集群,从中提取这些设置spark-defaults.conf
然后调整我的分类。否则,S3 访问之类的东西将无法工作。
创建集群时,在第1步中我在Edit software settings
中引用了上面的配置JSON文件,在第3步中,我将copylib.sh
配置为自定义 Bootstrap 操作。
我现在可以打开集群的 Jupyterhub,启动笔记本并使用我添加的功能。
我使用不使用 bootstrap 操作的替代方法。
- 将 JAR 放入 S3
- 将它们传递到
spark-submit
的 --jars
选项中,例如。 spark-submit --jars s3://my-bucket/extra-jars/*.jar
。所有的罐子都将被复制到集群中。
如果我们在集群创建期间错过了添加 bootstrap 操作,那么我们可以使用来自 s3 的任何 jar。
我使用 Spark 和 Livy 在 AWS 上创建了一个 EMR 集群。作为自定义 JAR 步骤,我提交了一个带有一些附加库(例如自定义格式的数据源)的自定义 JAR。但是,当我尝试从 Livy 访问自定义 JAR 中的内容时,它不可用。
我需要做什么才能使自定义内容在环境中可用?
我将此作为答案发布是为了能够接受它 - 由于 Yuval Itzchakov 的评论和关于自定义 Bootstrap 操作的 AWS 文档,我弄明白了。
这就是我所做的:
- 我将我的库 jar(用
sbt assembly
创建的包含所有所需内容的胖 jar)放入 S3 存储桶 创建了一个名为
copylib.sh
的脚本,其中包含以下内容:#!/bin/bash mkdir -p /home/hadoop/mylib aws s3 cp s3://mybucket/mylib.jar /home/hadoop/mylib
创建了以下配置 JSON 并将其放入除
mylib.jar
和copylib.sh
之外的同一个存储桶中:[{ "configurations": [{ "classification": "export", "properties": { "PYSPARK_PYTHON": "/usr/bin/python3" } }], "classification": "spark-env", "properties": {} }, { "configurations": [{ "classification": "export", "properties": { "PYSPARK_PYTHON": "/usr/bin/python3" } }], "classification": "yarn-env", "properties": {} }, { "Classification": "spark-defaults", "Properties": { "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/mylib/mylib.jar", "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/mylib/mylib.jar" } } ]
PySpark 需要
spark-env
和yarn-env
的分类才能通过 Livy 在 EMR 上使用 Python3。还有另一个问题:EMR 已经在两个extraClassPath
中填充了 EMR 正常运行所需的大量库,所以我不得不 运行 一个没有我的库的集群,从中提取这些设置spark-defaults.conf
然后调整我的分类。否则,S3 访问之类的东西将无法工作。创建集群时,在第1步中我在
Edit software settings
中引用了上面的配置JSON文件,在第3步中,我将copylib.sh
配置为自定义 Bootstrap 操作。
我现在可以打开集群的 Jupyterhub,启动笔记本并使用我添加的功能。
我使用不使用 bootstrap 操作的替代方法。
- 将 JAR 放入 S3
- 将它们传递到
spark-submit
的--jars
选项中,例如。spark-submit --jars s3://my-bucket/extra-jars/*.jar
。所有的罐子都将被复制到集群中。
如果我们在集群创建期间错过了添加 bootstrap 操作,那么我们可以使用来自 s3 的任何 jar。