![](/img/trans.png)
[英]How to copy data from Amazon AWS S3 Bucket into a MariaDB SQL table in Apache Airflow
[英]How to run Apache Spark applications with a JAR dependency from AWS S3?
我有一個.jar
文件,其中包含對位於 AWS S3 存儲桶中的應用程序有用的函數,我想將它用作 Spark 中的依賴項,而不必先在本地下載它。 是否可以使用spark-submit
(或pyspark
) --jars
選項直接引用.jar
文件?
到目前為止,我已經嘗試了以下方法:
spark-shell --packages com.amazonaws:aws-java-sdk:1.12.336,org.apache.hadoop:hadoop-aws:3.3.4 --jars s3a://bucket/path/to/jar/file.jar
正確設置了AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
變量,因為在沒有--jars
選項的情況下運行相同的命令時,可以成功讀取同一存儲桶中的其他文件。 但是,如果添加該選項,我會收到以下錯誤:
Exception in thread "main" java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2688)
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:3431)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:3466)
at org.apache.hadoop.fs.FileSystem.access$300(FileSystem.java:174)
at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:3574)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:3521)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:540)
at org.apache.spark.util.DependencyUtils$.resolveGlobPath(DependencyUtils.scala:317)
at org.apache.spark.util.DependencyUtils$.$anonfun$resolveGlobPaths$2(DependencyUtils.scala:273)
at org.apache.spark.util.DependencyUtils$.$anonfun$resolveGlobPaths$2$adapted(DependencyUtils.scala:271)
at scala.collection.TraversableLike.$anonfun$flatMap$1(TraversableLike.scala:293)
at scala.collection.IndexedSeqOptimized.foreach(IndexedSeqOptimized.scala:36)
at scala.collection.IndexedSeqOptimized.foreach$(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:38)
at scala.collection.TraversableLike.flatMap(TraversableLike.scala:293)
at scala.collection.TraversableLike.flatMap$(TraversableLike.scala:290)
at scala.collection.AbstractTraversable.flatMap(Traversable.scala:108)
at org.apache.spark.util.DependencyUtils$.resolveGlobPaths(DependencyUtils.scala:271)
at org.apache.spark.deploy.SparkSubmit.$anonfun$prepareSubmitEnvironment$4(SparkSubmit.scala:364)
at scala.Option.map(Option.scala:230)
at org.apache.spark.deploy.SparkSubmit.prepareSubmitEnvironment(SparkSubmit.scala:364)
at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:901)
at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:180)
at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:203)
at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:90)
at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:1046)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:1055)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found
at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:2592)
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2686)
... 27 more
我正在使用為 Apache Hadoop 3.3 及更高版本預構建的 Spark 3.3.1。
這可能是因為在客戶端模式下 - Spark 在啟動期間首先通過 Netty 分發 Jars(在 --jars 中指定)。 要從第三方文件系統(即 S3)下載遠程 JAR,它需要類路徑中已經存在正確的依賴項(即 hadoop-aws)(在准備最終類路徑之前)。
但由於它尚未分發 JARs,它還沒有准備好類路徑 - 因此當它嘗試從 s3 下載 JAR 時,它因 ClassNotFound 而失敗(因為 hadoop-aws 尚未在類路徑上),但在執行相同操作時在應用程序代碼中它成功了——因為那時類路徑已經被解析。
即下載依賴是依賴一個庫,后面會加載。
要從 Amazon S3 運行具有 JAR 依賴項的 Apache Spark 應用程序,您可以在提交 Spark 應用程序時使用 --jars 命令行選項指定 JAR 文件的 S3 URL。
比如你的JAR文件存放在my-bucket S3 bucket的jars/my-jar.jar路徑下,你可以提交Spark申請如下:
spark-submit --jars s3a://my-bucket/jars/my-jar.jar \
--class com.example.MySparkApp \
s3a://my-bucket/my-spark-app.jar
這將從 S3 下載 JAR 文件並將其添加到 Spark 應用程序的類路徑中。
請注意,您需要在 S3 URL 中包含 s3a:// 前綴才能使用 s3a 文件系統連接器,這是用於讀取和寫入 S3 的推薦連接器。 您可能還需要使用 AWS 訪問密鑰和秘密密鑰配置 fs.s3a.access.key 和 fs.s3a.secret.key 屬性,以便驗證與 S3 的連接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.