EMR w/multiple JDBC 个罐子上的 Spark

Spark on EMR w/multiple JDBC jars

我的设置:构建的小型 Spark 项目 w/SBT(+ 用于制作 "fat" jar 的 sbt-assembly)需要使用 JDBC(Postgre[=37)与多个数据库后端通信=] + SQL 服务器在这种情况下,但我认为我的问题普遍存在)。我可以在本地驱动程序模式下毫无问题地构建 + 运行 我的项目,使用完全着色的 JAR 或使用 spark-submit 添加到类路径的纤细的 w/JDBC 库。我已经确认类文件在我的 jar 中,并且各种驱动程序正确地连接到 META-INF/services/java.sql.Driver,并且当胖 JAR 在我的类路径中时,可以通过 Scala repl 加载任何有问题的 类 .

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

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

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

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

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

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()