【问题标题】:Spark - jdbc write fails in Yarn cluster mode but works in spark-shellSpark - 在 Yarn 集群模式下 jdbc 写入失败,但在 spark-shell 中工作
【发布时间】:2017-01-05 16:01:01
【问题描述】:

我正在使用 Spark 1.6.2、Hadoop 2.6、Scala 2.10.5 和 Java 1.7

我正在使用 JDBC 从 MSSQL 读取数据,这没有任何问题:

val hqlContext = new HiveContext(sc)

val url = "jdbc:sqlserver://1.1.1.1:1111;database=CIQOwnershipProcessing;user=OwnershipUser;password=Ownership123"

val driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";

val df1 = hqlContext.read.format("jdbc").options(
   Map("url" -> url, "driver" -> driver,
  "dbtable" -> "(select * from OwnershipStandardization_PositionSequence_tbl) as ps")).load()

并且,在将数据帧回写到 MSSQL 时,我正在使用 JDBC 写入,如下所示。这在 Spark-shell 中工作正常,但当我在 Yarn-Cluster 模式下执行 spark-submit 时失败。我错过了什么?

val prop = new java.util.Properties
df1.write.mode("Overwrite").jdbc(url, "CIQOwnershipProcessing.dbo.df_sparkop",prop)

这就是我的 spark-submit 命令的样子。如您所见,我也传递了 SQLJDBC jar 路径。而且,我还在集群的所有节点上的 spark-defaults.conf 中的“spark.executor.extraClassPath”属性中指定了 jdbc jar 路径。由于 JDBC 读取工作正常,我怀疑它是否与类路径有关。

spark-submit --class com.spgmi.csd.OshpStdCarryOver --master  yarn --deploy-mode cluster --conf spark.yarn.executor.memoryOverhead=2048 --num-executors 1 --executor-cores 2 --driver-memory 3g --executor-memory 8g --jars $SPARK_HOME/lib/datanucleus-api-jdo-3.2.6.jar,$SPARK_HOME/lib/datanucleus-core-3.2.10.jar,$SPARK_HOME/lib/datanucleus-rdbms-3.2.9.jar,/usr/share/java/sqljdbc_4.1/enu/sqljdbc41.jar --files $SPARK_HOME/conf/hive-site.xml $SPARK_HOME/lib/spark-poc2-17.1.0.jar

Yarn-Cluster模式抛出的错误是:

17/01/05 10:21:31 错误 yarn.ApplicationMaster: 用户类抛出 异常:java.lang.InstantiationException: org.apache.spark.sql.execution.datasources.jdbc.DriverWrapper java.lang.InstantiationException: org.apache.spark.sql.execution.datasources.jdbc.DriverWrapper 在 java.lang.Class.newInstance(Class.java:368) 在 org.apache.spark.sql.execution.datasources.jdbc.DriverRegistry$.register(DriverRegistry.scala:46) 在 org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$createConnectionFactory$2.apply(JdbcUtils.scala:53) 在 org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$createConnectionFactory$2.apply(JdbcUtils.scala:52) 在 org.apache.spark.sql.DataFrameWriter.jdbc(DataFrameWriter.scala:27​​8) 在 com.spgmi.csd.OshpStdCarryOver$.main(SparkOshpStdCarryOver.scala:175) 在 com.spgmi.csd.OshpStdCarryOver.main(SparkOshpStdCarryOver.scala) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:606) 在 org.apache.spark.deploy.yarn.ApplicationMaster$$anon$2.run(ApplicationMaster.scala:558)

【问题讨论】:

    标签: sql-server scala hadoop apache-spark jdbc


    【解决方案1】:

    我也面临同样的问题。我通过在 prop 中设置连接属性来解决它。

    val prop = new java.util.Properties
    prop.setProperty("driver","com.mysql.jdbc.Driver")
    

    现在传递这个道具

    df1.write.mode("Overwrite").jdbc(url, "CIQOwnershipProcessing.dbo.df_sparkop",prop)
    

    【讨论】:

      【解决方案2】:

      您的问题与SPARK-14204 和SPARK-14162 非常相似——尽管该错误本应在Spark 1.6.2 中修复(?!)

      对于 Type 4 JDBC 驱动程序,您不必明确提及“驱动程序”属性; JAR 应自动注册它支持的 URL 前缀(此处为 jdbc:sqlserver:)。
      但由于该错误,Spark JDBC 模块可能不会使用该“注册”来查找 隐式 匹配 URL 的驱动程序。

      换句话说:为了阅读,你强制“驱动程序”属性和连接工作;对于写作,你不强迫它,它不起作用。啊哈!

      【讨论】:

      • 是的,这就是我想知道的。您如何强制 JDBC 写入中的“驱动程序”属性?谢谢!
      • Spark 文档没有说明“驱动程序”是特定于阅读的,那么 df1.write.mode("Overwrite").format("jdbc").options(Map("url" -> url, "driver" -> driver, "dbtable" -> "xxxxx")).save() 呢?参照。例如github.com/apache/spark/blob/master/sql/core/src/test/scala/org/… 中的单元测试。
      • 不行,我看到这个错误:17/01/10 06:12:13 ERROR yarn.ApplicationMaster: User class threw exception: java.lang.RuntimeException: org.apache.spark.sql.execution.datasources.jdbc.DefaultSource does not allow create table as select. java.lang.RuntimeException: org.apache.spark.sql.execution.datasources.jdbc.DefaultSource does not allow create table as select.
      • @Prash,这是一个不同的问题——我猜Spark不支持Overwrite模式来保存JDBC;尝试使用Append 模式。
      • 嗨 Samson,还是没有运气。得到完全相同的错误。这就是我的 jdbc 写入语句的样子:df1_rnum.write.mode("Append").format("jdbc").options(Map("url" -> url, "driver" -> driver, "dbtable" -> "CIQOwnershipProcessing.dbo.df_rnum_sparkop")).save()
      猜你喜欢
      • 2017-03-10
      • 1970-01-01
      • 2023-04-08
      • 2015-11-06
      • 2016-01-13
      • 2014-11-04
      • 2019-03-10
      • 2016-11-11
      • 1970-01-01
      相关资源
      最近更新 更多