我的设置:使用 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/