
在spark流处理中向mongodb写入数据时,常见的`nosuchmethoderror`通常源于`mongo-spark-connector`与spark版本之间的不兼容。本文将深入分析这一错误,并提供解决方案:针对spark 3.5.0版本,应使用`mongo-spark-connector` 10.3及更高版本,以确保api调用匹配,从而实现数据的平滑写入。
Apache Spark以其强大的数据处理能力,常被用于处理大规模数据集。当需要将处理后的数据持久化到NoSQL数据库如MongoDB时,mongo-spark-connector扮演着关键角色,它允许Spark DataFrame和Dataset直接与MongoDB进行交互。然而,由于Spark和连接器都在持续迭代更新,版本兼容性问题成为集成过程中一个常见的挑战。
当尝试使用Spark将数据写入MongoDB时,如果遇到类似以下堆栈跟踪中的java.lang.NoSuchMethodError错误:
java.lang.NoSuchMethodError: org.apache.spark.sql.catalyst.encoders.RowEncoder$.apply(Lorg/apache/spark/sql/types/StructType;)Lorg/apache/spark/sql/catalyst/encoders/ExpressionEncoder;
at com.mongodb.spark.sql.connector.schema.InternalRowToRowFunction.<init>(InternalRowToRowFunction.java:44)
at com.mongodb.spark.sql.connector.schema.RowToBsonDocumentConverter.<init>(RowToBsonDocumentConverter.java:84)
at com.mongodb.spark.sql.connector.write.MongoDataWriter.<init>(MongoDataWriter.java:74)
...这个错误表明mongo-spark-connector内部尝试调用Spark SQL核心库中的一个方法(org.apache.spark.sql.catalyst.encoders.RowEncoder$.apply),但该方法在当前运行的Spark版本中签名不匹配或根本不存在。这通常是由于连接器是为旧版Spark编译的,而您正在使用较新版本的Spark,导致Spark内部API发生了变化,从而引发了运行时错误。在上述案例中,Spark 3.5.0的RowEncoder实现与mongo-spark-connector 10.2.1所期望的不一致。
解决此类兼容性问题的核心在于确保所使用的mongo-spark-connector版本与您的Spark版本完全兼容。对于Spark 3.5.0,官方推荐使用mongo-spark-connector 10.3或更高版本。这些新版本已经更新以适应Spark 3.1至3.5.0之间的API变化。
在选择连接器版本时,首先需要明确您的Spark版本和Scala版本。例如,如果使用Spark 3.5.0和Scala 2.12,那么连接器也应选择针对Scala 2.12编译的版本。
在Spark应用程序中,通过spark.jars.packages配置项指定mongo-spark-connector的正确版本。将旧的连接器版本替换为兼容的新版本。
以下是更新后的SparkSession配置示例:
# 假设 scala_version 和 spark_version 已定义
scala_version = "2.12" # 示例值,请根据实际环境设置
spark_version = "3.5.0" # 示例值,请根据实际环境设置
# ----------------------------------------------------------
packages = [
f'org.apache.spark:spark-sql-kafka-0-10_{scala_version}:{spark_version}',
'org.apache.kafka:kafka-clients:3.5.0',
'org.apache.hadoop:hadoop-client:3.0.0',
'org.elasticsearch:elasticsearch-spark-30_2.12:7.17.16',
# 将 mongo-spark-connector 版本更新为 10.3.1 (或更高版本,以兼容Spark 3.5.0)
"org.mongodb.spark:mongo-spark-connector_2.12:10.3.1"
]
spark = SparkSession.builder \
.master(MASTER) \
.appName("Movie Consumer") \
.config("spark.jars.packages", ",".join(packages)) \
.config(f"spark.mongodb.input.uri", f"mongodb+srv://{USERNAME}:{PASSWORD}@atlascluster.zdoemtz.mongodb.net") \
.config(f"spark.mongodb.output.uri", f"mongodb+srv://{USERNAME}:{PASSWORD}@atlascluster.zdoemtz.mongodb.net") \
.config("spark.cores.max", "1") \
.config("spark.executor.memory", "1g") \
.getOrCreate()
spark.sparkContext.setLogLevel("Error")
# 示例写入函数(保持不变,因为问题出在依赖版本)
def write_to_db(df, epoch_id):
df.select("id", "production_companies").show()
df.write.format("mongodb") \
.mode("append") \
.option("database", "BIGDATA") \
.option("collection", "movie") \
.save()
# 假设您有一个流式DataFrame 'streaming_df'
# streaming_df.writeStream \
# .foreachBatch(write_to_db) \
# .outputMode("update") \
# .start() \
# .awaitTermination()请注意,mongo-spark-connector_2.12:10.3.1中的10.3.1是建议的版本,您也可以查阅MongoDB官方文档以获取最新的兼容版本信息。
java.lang.NoSuchMethodError是Spark生态系统中常见的版本不兼容问题之一。通过将mongo-spark-connector更新到与Spark 3.5.0兼容的10.3或更高版本,可以有效解决在Spark中向MongoDB写入数据时遇到的此类错误。遵循官方兼容性指南和最佳实践,是确保Spark应用程序稳定运行的关键。
以上就是Spark与MongoDB集成:解决版本不兼容导致的写入错误的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号