具有多个JDBC jar的EMR上的Spark

时间:2018-01-29 19:41:27

标签: apache-spark jdbc sbt emr

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

现在的问题是:没有构建选项,作业提交选项等的组合。一旦我将作业提交给EMR,我可以解开,允许我访问> 1 JDBC驱动程序。我尝试了普通的胖JAR以及通过各种spark-submit选项(--jars--packages等)添加驱动程序。在每种情况下,我的工作都会抛出“不合适的驱动程序”错误,但只能加载第二个驱动程序。另外一个问题:我通过EC2主机而不是我的本地开发机器(b / c云安全,这就是为什么)将工作提交给EMR,但无论如何都是相同的JAR。

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

我一直在讨论这个问题已经有几天了,老实说,我开始担心这是一个潜在的类加载器问题或类似的问题。

一些标准的免责声明:这不是一个开源工具,因此我不能对源代码或原始日志做出太多分析,但我很高兴看到并报告任何可能适当的内容中删除。

1 个答案:

答案 0 :(得分:1)

由于您的调查没有显示任何明显的问题,因此可能只是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()