【问题标题】:Adding JDBC driver to Spark on EMR在 EMR 上将 JDBC 驱动程序添加到 Spark
【发布时间】:2015-12-21 18:15:16
【问题描述】:

我正在尝试将 JDBC 驱动程序添加到在顶级 Amazon EMR 上执行的 Spark 集群,但我不断收到:

java.sql.SQLException: 没有找到适合异常的驱动程序。

我尝试了以下方法:

  1. 使用 addJar 从代码中显式添加驱动程序 Jar。
  2. 使用 spark.executor.extraClassPath spark.driver.extraClassPath 参数。
  3. 使用 spark.driver.userClassPathFirst=true,当我使用此选项时,我得到一个不同的错误,因为 Spark 的依赖项混合在一起,无论如何,如果我只想添加一个 JAR,此选项似乎过于激进。

您能帮我解决这个问题吗?如何轻松地将驱动程序引入 Spark 集群?

谢谢,

大卫

应用程序源代码

val properties = new Properties()
properties.put("ssl", "***")
properties.put("user", "***")
properties.put("password", "***")
properties.put("account", "***")
properties.put("db", "***")
properties.put("schema", "***")
properties.put("driver", "***")

val conf = new SparkConf().setAppName("***")
      .setMaster("yarn-cluster")
      .setJars(JavaSparkContext.jarOfClass(this.getClass()))

val sc = new SparkContext(conf)
sc.addJar(args(0))
val sqlContext = new SQLContext(sc)

var df = sqlContext.read.jdbc(connectStr, "***", properties = properties)
df = df.select( Constants.***,
                Constants.***,
                Constants.***,
                Constants.***,
                Constants.***,
                Constants.***,
                Constants.***,
                Constants.***,
                Constants.***)
// Additional actions on df

【问题讨论】:

  • 您是否尝试在您的应用程序 jar 中插入 jdbc jar?
  • 是的,我做到了。 jar 是我的项目类路径的一部分。当我在本地执行代码时,它运行良好,只有在 Amazon EMR 上我遇到了困难。
  • 你可以尝试用你的 jar 的内容来编辑你的问题吗?
  • 当然。我不能放我的整个源代码,但我会复制粘贴主要部分。
  • Ofc,我们不需要完整的源代码

标签: jdbc apache-spark amazon-emr


【解决方案1】:

遵循与this answer quoted above 类似的模式,这就是我在 EMR 集群上自动安装 JDBC 驱动程序的方式。 (完全自动化对于每个作业启动和终止的临时集群很有用。)

  • 使用引导操作在所有 EMR 集群节点上安装 JDBC 驱动程序。您的引导操作将是一个存储在 S3 中的单行 shell 脚本,看起来像
aws s3 cp s3://.../your-jdbc-driver.jar /home/hadoop
  • 在运行实际 Spark 作业之前向 EMR 集群添加一个步骤,以修改 /etc/spark/conf/spark-defaults.conf

这将是另一个单行 shell 脚本,存储在 S3 中:

sudo sed -e 's,\(^spark.driver.extraClassPath.*$\),\1:/home/hadoop/your-jdbc-driver.jar,' -i /etc/spark/conf/spark-defaults.conf

步骤本身看起来像

{
    "name": "add JDBC driver to classpath",
    "jar": "s3://us-east-1.elasticmapreduce/libs/script-runner/script-runner.jar",
    "args": ["s3://...bucket.../set-spark-driver-classpath.sh"]
}

这会将您的 JDBC 驱动程序添加到 spark.driver.extraClassPath

解释

  • 您不能同时执行这两个引导操作,因为 Spark 尚未安装,因此没有要更新的配置文件

  • 您不能将 JDBC 驱动程序作为一个步骤安装,因为您需要将 JDBC 驱动程序安装在 所有 个集群节点上的同一路径上。 YARN集群模式下,驱动进程不一定运行在主节点上。

  • 不过,配置只需要在主节点上更新,因为配置已打包并运送到最终运行驱动程序的任何节点。

【讨论】:

    【解决方案2】:

    使用 EMR 5.2,我将任何新 jar 添加到原始驱动程序 classpath 中:

    export MY_DRIVER_CLASS_PATH=my_jdbc_jar.jar:some_other_jar.jar$(grep spark.driver.extraClassPath /etc/spark/conf/spark-defaults.conf | awk '{print $2}')
    

    然后

    spark-submit --driver-class-path $MY_DRIVER_CLASS_PATH
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。最终对我有用的是使用与 spark-submit 一起使用的 --driver-class-path 参数。

      主要是将整个spark类路径添加到--driver-class-path

      这是我的步骤:

      1. 我通过获取 Spark 历史服务器中的“spark.driver.extraClassPath”属性 在“环境”下。
      2. 将 MySQL JAR 文件复制到 EMR 集群中的每个节点。
      3. 将 MySQL jar 路径放在 spark-submit 命令的 --driver-class-path 参数的前面,并将“spark.driver.extraClassPath”的值附加到它

      我的驱动程序类路径最终看起来像这样:

      --driver-class-path /home/hadoop/jars/mysql-connector-java-5.1.35.jar:/etc/hadoop/conf:/usr/lib/hadoop/:/usr/ lib/hadoop-hdfs/:/usr/lib/hadoop-mapreduce/:/usr/lib/hadoop-yarn/:/usr/lib/hadoop-lzo/lib/:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/:/usr/share/aws/emr/emrfs/auxlib/* p>

      这适用于 EMR 4.1,使用 Java 和 Spark 1.5.0。 我已经在 Maven pom.xml 中添加了 MySQL JAR 作为依赖项

      您可能还想查看this answer,因为它似乎是一个更清洁的解决方案。我自己没试过。

      【讨论】:

        猜你喜欢
        • 2016-01-02
        • 2018-11-12
        • 2021-07-07
        • 2015-06-15
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多