在EMR上向Spark添加JDBC驱动程序

时间:2015-09-24 08:05:04

标签: jdbc apache-spark amazon-emr

我试图将JDBC驱动程序添加到在顶级Amazon EMR上执行的Spark群集中,但我一直得到:

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

我尝试了以下事项:

  1. 使用addJar从代码中明确添加驱动程序Jar。
  2. 使用spark.executor.extraClassPath spark.driver.extraClassPath参数。
  3. 使用spark.driver.userClassPathFirst = true,当我使用这个选项时我得到了一个不同的错误,因为依赖与Spark的混合,无论如何这个选项似乎是积极的,如果我只是想添加一个JAR
  4. 请您帮我解决一下,如何轻松地将驱动程序引入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
    

3 个答案:

答案 0 :(得分:1)

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

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

以下是我的步骤:

  1. 我通过获取的值得到了默认的驱动程序类路径 Spark History Server中的“spark.driver.extraClassPath”属性 在“环境”下。
  2. 将MySQL JAR文件复制到EMR集群中的每个节点。
  3. 将MySQL jar路径放在spark-submit命令的--driver-class-path参数的前面,并将“spark.driver.extraClassPath”的值附加到它
  4. 我的驱动程序类路径最终看起来像这样:

      

    - 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的映射精简/ :/ usr / lib中/ Hadoop的纱线/ :/ usr / lib中/ Hadoop的LZO / LIB / < EM>:在/ usr /共享/ AWS / EMR / emrfs / CONF:在/ usr /共享/ AWS / EMR / emrfs / LIB / :在/ usr /共享/ AWS / EMR / emrfs / auxlib / *

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

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

答案 1 :(得分: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驱动程序安装在 all 集群节点上的同一路径上。在YARN群集模式下,驱动程序进程不一定在主节点上运行。

  • 不过,仅需在主节点上更新配置,因为打包并运送了配置,无论最终运行驱动程序的节点是什么。

答案 2 :(得分:0)

使用EMR 5.2,我将所有新罐子添加到原始驱动程序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