如何使用用户提供的 Hadoop 正确配置 Spark 2.4
Posted
技术标签:
【中文标题】如何使用用户提供的 Hadoop 正确配置 Spark 2.4【英文标题】:How to configure Spark 2.4 correctly with user-provided Hadoop 【发布时间】:2020-06-14 12:05:42 【问题描述】:我想使用 Spark 2.4.5(当前稳定的 Spark 版本)和 Hadoop 2.10(当前稳定的 Hadoop 2.x 系列版本)。此外,我还需要访问 HDFS、Hive、S3 和 Kafka。
http://spark.apache.org 提供预先构建的 Spark 2.4.5,并与 Hadoop 2.6 或 Hadoop 2.7 捆绑在一起。 另一种选择是将 Spark 与用户提供的 Hadoop 一起使用,所以我尝试了那个。
由于与用户提供的 Hadoop 一起使用,Spark 也不包含 Hive 库。 会有错误,像这里:How to create SparkSession with Hive support (fails with "Hive classes are not found")?
当我将 spark-hive 依赖项添加到 spark-shell 时(spark-submit 也会受到影响)使用
spark.jars.packages=org.apache.spark:spark-hive_2.11:2.4.5
在 spark-defaults.conf 中,我收到此错误:
20/02/26 11:20:45 ERROR spark.SparkContext:
Failed to add file:/root/.ivy2/jars/org.apache.avro_avro-mapred-1.8.2.jar to Spark environment
java.io.FileNotFoundException: Jar /root/.ivy2/jars/org.apache.avro_avro-mapred-1.8.2.jar not found
at org.apache.spark.SparkContext.addJarFile$1(SparkContext.scala:1838)
at org.apache.spark.SparkContext.addJar(SparkContext.scala:1868)
at org.apache.spark.SparkContext.$anonfun$new$11(SparkContext.scala:458)
at org.apache.spark.SparkContext.$anonfun$new$11$adapted(SparkContext.scala:458)
at scala.collection.immutable.List.foreach(List.scala:392)
at org.apache.spark.SparkContext.<init>(SparkContext.scala:458)
at org.apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2520)
at org.apache.spark.sql.SparkSession$Builder.$anonfun$getOrCreate$5(SparkSession.scala:935)
at scala.Option.getOrElse(Option.scala:189)
at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:926)
at org.apache.spark.repl.Main$.createSparkSession(Main.scala:106)
因为 spark-shell 无法同时处理分类器和捆绑包依赖关系,请参阅 https://github.com/apache/spark/pull/21339 和 https://github.com/apache/spark/pull/17416
分类器问题的解决方法如下所示:
$ cp .../.ivy2/jars/org.apache.avro_avro-mapred-1.8.2-hadoop2.jar .../.ivy2/jars/org.apache.avro_avro-mapred-1.8.2.jar
但 DevOps 不会接受这一点。
完整的依赖列表如下所示(为了更好的可读性,我添加了换行符)
root@a5a04d888f85:/opt/spark-2.4.5/conf# cat spark-defaults.conf
spark.jars.packages=com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.10,
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.10,
org.apache.spark:spark-hive_2.11:2.4.5,
org.apache.spark:spark-sql-kafka-0-10_2.11:2.4.5,
org.apache.hadoop:hadoop-aws:2.10.0,
io.delta:delta-core_2.11:0.5.0,
org.postgresql:postgresql:42.2.5,
mysql:mysql-connector-java:8.0.18,
com.datastax.spark:spark-cassandra-connector_2.11:2.4.3,
io.prestosql:presto-jdbc:307
(一切正常 - 除了 Hive)
Spark 2.4.5 和 Hadoop 2.10 的组合是否可以在任何地方使用?怎么样? 如何将 Spark 2.4.5 与用户提供的 Hadoop 和 Hadoop 2.9 或 2.10 结合起来? 是否有必要构建 Spark 来解决 Hive 依赖问题?【问题讨论】:
对有关预构建版本的评论感到好奇。我只看到 Hadoop 2.6 和 Hadoop 2.7 的预构建二进制文件,但这表明可用性是 Hadoop 2.7 和 Hadoop 2.8。这是一个错误的错误,还是发生了一些变化? 我想将我的 hadoop aws 升级到 3.2。目前坚持对 hadoop 2.7 的火花依赖。是否可以遮蔽hadoop aws?我将使用 uber jar。 @Knight71 它可能适用于您的情况。然而,根据我的经验,这通常会导致问题,尤其是在 AWS 依赖项的情况下。正是出于这个原因,我构建了 Spark(具有一致的)依赖关系。 Spark 集群在 2.2.1 中,预构建了 hadoop 2.7。它不起作用,因为 2.7 jars 已经存在于类路径中。获取 hadoop 配置的 ClassNotFound 错误。 【参考方案1】:似乎没有一种简单的方法来配置 Spark 2.4.5 和用户提供的 Hadoop 以使用 Hadoop 2.10.0
因为我的任务实际上是最小化依赖问题,所以我选择了compile Spark 2.4.5 与 Hadoop 2.10.0。
./dev/make-distribution.sh \
--name hadoop-2.10.0 \
--tgz \
-Phadoop-2.7 -Dhadoop.version=hadoop-2.10.0 \
-Phive -Phive-thriftserver \
-Pyarn
现在 Maven 处理 Hive 依赖项/分类器,生成的包可以使用了。
在我个人看来,编译 Spark 实际上比使用用户提供的 Hadoop 配置 Spark 更容易。
到目前为止,集成测试没有显示任何问题,Spark 可以访问 HDFS 和 S3 (MinIO)。
2021-04-08 更新
如果您想添加对 Kubernetes 的支持,只需将 -Pkubernetes
添加到参数列表中
【讨论】:
这种方法看起来不错。我成功地对 Hadoop 2.8.5 的目标版本做了同样的事情。为了更加放心,我比较了 Spark 构建配置文件中每个覆盖的版本,发现它们根本没有改变。我怀疑 Hadoop 2.10.0 也是如此。设置 -Dhadoop.version 似乎不会影响编译,只会影响捆绑的依赖项,这是您在自定义your-own-Hadoop
版本时手动调整的内容,方法是从选定的 hadoop 版本中放入 jar 包。这只是允许构建系统为您完成这项工作。
这似乎也是使用目标 Hadoop 版本构建的文档提供的方法。值得仔细研究这些方向 - 否则您会错过设置 MAVEN_OPTS 以解决构建的内存要求等内容! spark.apache.org/docs/latest/…【参考方案2】:
假设您不想运行 Spark-on-YARN —— 从 bundle "Spark 2.4.5 with Hadoop 2.7" 开始,然后挑选 Hadoop 库从 bundle “Hadoop 2.10.x”
-
丢弃
spark-yarn
/ hadoop-yarn-*
/ hadoop-mapreduce-client-*
JAR,因为您不需要它们,除了 hadoop-mapreduce-client-core
被 HDFS 和 S3 上的写操作引用(参见“MR提交程序”V1 或 V2)
您还可以丢弃 spark-mesos
/ mesos-*
和/或 spark-kubernetes
/ kubernetes-*
JAR,具体取决于您计划运行 Spark 的对象
如果您不打算运行“thrift server”实例,您也可以丢弃spark-hive-thriftserver
和hive-*
JARS,除了 hive-metastore
是必要的,正如您可能猜到的那样,管理 Metastore (常规 Hive Metastore 服务或 Spark 会话中的嵌入式 Metastore)
丢弃hadoop-hdfs
/ hadoop-common
/ hadoop-auth
/ hadoop-annotations
/ htrace-core*
/ xercesImpl
JAR
替换为hadoop-hdfs-client
/hadoop-common
/hadoop-auth
/hadoop-annotations
/htrace-core*
/xercesImpl
/stax2-api
来自 Hadoop 2.10 的 JAR(在 @9876543445@@ 和 @98765454 下)和hdfs/lib/
)
从 Hadoop 2.10 添加 S3A 连接器,即 hadoop-aws
/ jets3t
/ woodstox-core
JAR(在 tools/lib/
下)
从 Amazon 下载 aws-java-sdk
(我猜它不是 Apache 许可证,因此不能与 Hadoop 捆绑)
最后,运行大量测试...
这对我有用,经过一些试验和错误 - 需要注意的是:我针对 S3 兼容的存储系统运行我的测试,但不是针对“真正的”S3,而不是针对常规 HDFS .并且没有“真正的”Hive Metastore 服务,只有 Spark 默认运行的嵌入式内存和易失性 Metastore。
作为记录,该过程与 Spark 3.0.0 预览版和 Hadoop 3.2.1 相同,不同之处在于 你还得升级
guava
您不必升级xercesImpl
或htrace-core
或stax2-api
你不再需要jets3t
您需要保留更多 hadoop-mapreduce-client-*
JAR(可能是因为新的“S3 提交者”)
【讨论】:
不认为您有一个 bash 脚本来设置它? ;) 我的 client 拥有该脚本......而且他们非常固执地不分享任何内容,无论出于何种原因。 嗯。在 Ansible/Chef 中重写所述脚本? :) 感谢您非常详细的回答。所以确实不容易。我今天会进行一些测试,稍后再提供反馈。以上是关于如何使用用户提供的 Hadoop 正确配置 Spark 2.4的主要内容,如果未能解决你的问题,请参考以下文章
如何配置 Undertow 处理程序以支持正确重写 SPA 书签?
处理django rest framework + vue SPA auth
如何使用 React 和 Firebase 托管在 SPA 上提供 robots.txt?
处理 django rest framework + vue SPA auth