apache-spark - 带有多个 JDBC jar 的 EMR 上的 Spark

标签 apache-spark jdbc sbt emr

我的设置:使用 SBT(+ 用于制作“胖” jar 的 sbt-assembly)构建的小型 Spark 项目需要使用 JDBC(本例中为 PostgreSQL + SQL Server)与多个数据库后端通信,但我认为我的问题具有普遍性).我可以在本地驱动程序模式下毫无问题地构建和运行我的项目,使用完全着色的 JAR 或使用 spark-submit 添加到类路径的带有 JDBC 库的超薄 JAR。我已经确认类文件在我的 jar 中并且各种驱动程序正确地连接到 META-INF/services/java.sql.Driver 中,并且可以通过 Scala 加载任何有问题的类当胖 JAR 在我的类路径中时回复。

现在的问题是:没有构建选项、作业提交选项等的组合。一旦我将作业提交给 EMR,我就无法理解是否允许我访问 >1 个 JDBC 驱动程序。我已经尝试了普通的胖 JAR 以及通过各种 spark-submit 选项(--jars--packages 等)添加驱动程序。在每种情况下,我的工作都会抛出良好的“没有合适的驱动程序”错误,但仅针对要加载的第二个驱动程序。一个额外的问题:我通过 EC2 主机而不是我的本地开发机器(b/c 云安全,这就是原因)将作业提交给 EMR,但在任何一种情况下它都是相同的 JAR。

另一个有趣的数据点:我已经验证了驱动程序类在运行时在 EMR 作业中可用,方法是在实际尝试之前对每个驱动程序强制执行 Class.forName(...)连接。看不到任何一个 ClassNotFoundException。同样,放入 EMR 主节点上的 spark-shell 并运行相同的代码路径来获取数据库连接(或多个!)似乎工作正常。

几天来我一直在研究这个问题,老实说,我开始担心这是一个潜在的类加载器问题或其他同样迟钝的问题。

一些标准的免责声明:这不是一个开源工具,所以我不能提供太多源代码或原始日志,但我很乐意查看并报告任何适合的东西编辑。

最佳答案

由于您的调查没有显示任何明显的问题,这可能只是一个 Spark 问题。在这种情况下,显式声明驱动程序类可能会有所帮助:

val postgresDF = spark.read
  .format("jdbc")
  .option("driver" , "org.postgresql.Driver")
  ...
  .load()

val msSQLDF = spark.read
  .format("jdbc")
  .option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
  ...
  .load()

关于apache-spark - 带有多个 JDBC jar 的 EMR 上的 Spark,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48508806/

相关文章:

java - Hive 模拟不适用于 jdbc

playframework - 自定义 logback 适配器类仅在 jar 文件中找到

scala - 如何使用 scala/spark 正确迭代/打印 Parquet ?

amazon-web-services - AWS EMR 上的 Spark 独立模式

java - 关闭数据库连接后从 Oracle DB 读取 CLOB

java - 找不到 jdbcDrive 类

scala - 可以使用 sbt 访问非 scala github 存储库来读入 scala 项目吗?

scala - Akka-Http 2.4.9 抛出 java.lang.NoClassDefFoundError : akka/actor/ActorRefFactory exception

python - 在 Python 中创建自定义 Spark RDD

使用 Java 将 JavaPairRDD 转换为 Apache Spark 中的 DataFrame