Spark не может найти драйвер JDBC

Итак, я использовал sbt со сборкой, чтобы упаковать все мои зависимости в одну банку для моих искровых заданий. У меня есть несколько заданий, на которых я использовал c3p0 для настройки информации о пуле соединений, транслировал ее, а затем использовал foreachPartition в RDD, чтобы затем захватить соединение и вставить данные в базу данных. В моем сценарии сборки sbt я включаю

"mysql" % "mysql-connector-java" % "5.1.33"

Это гарантирует, что соединитель JDBC упакован вместе с заданием. Все отлично работает.

Так недавно я начал экспериментировать со SparkSQL и понял, что намного проще просто взять фрейм данных и сохранить его в источник jdbc с новыми функциями в 1.3.0

У меня следующее исключение:

java.sql.SQLException: не найден подходящий драйвер для jdbc: mysql: //some.domain.com/myschema? user = user & password = password в java.sql.DriverManager.getConnection (DriverManager.java:596) в java.sql. DriverManager.getConnection (DriverManager.java:233)

Когда я запускал это локально, я обошел это, установив

SPARK_CLASSPATH=/path/where/mysql-connector-is.jar

В конечном итоге я хочу знать, почему эта работа не может найти драйвер, когда он должен быть упакован вместе с ним? На других моих работах никогда не было такой проблемы. Из того, что я могу сказать, и c3p0, и код фрейма данных используют java.sql.DriverManager (который обрабатывает для вас импорт всего, насколько я могу судить), поэтому он должен работать нормально ?? Если есть что-то, что мешает работе метода сборки, что мне нужно сделать, чтобы это сработало?


person Adam Ritter    schedule 10.04.2015    source источник
comment
Как вы начинаете свою работу? Вы проверили, что ваш собранный jar включает драйвер MySQL?   -  person Daniel Darabos    schedule 10.04.2015
comment
Я проверил банку, она действительно содержит драйвер MySQL. Я запускаю свою работу с помощью bin / spark-submit --class com.mypackage.MyJob --verbose spark: //place.where.this.exists.com: 7077 MyJob.jar   -  person Adam Ritter    schedule 10.04.2015
comment
У меня такая же проблема, я тоже пытаюсь сохранить в mysql. Вы когда-нибудь разбирались в этом?   -  person Marcin    schedule 22.10.2015


Ответы (10)


У этого человека была аналогичная проблема: http://apache-spark-user-list.1001560.n3.nabble.com/How-to-use-DataFrame-with-MySQL-td22178.html

Вы обновили драйверы разъема до последней версии? Также вы указали класс драйвера при вызове load ()?

Map<String, String> options = new HashMap<String, String>();
options.put("url", "jdbc:mysql://localhost:3306/video_rcmd?user=root&password=123456");
options.put("dbtable", "video");
options.put("driver", "com.mysql.cj.jdbc.Driver"); //here
DataFrame jdbcDF = sqlContext.load("jdbc", options); 

В spark / conf / spark-defaults.conf вы также можете установить spark.driver.extraClassPath и spark.executor.extraClassPath на путь к вашему MySql-драйверу .jar.

person insomniak    schedule 11.04.2015
comment
Добавление путей jar в spark-defaults.conf сделало свою работу! (если это не удается, попробуйте воссоздать кластер и добавить банки) - person Sincole Brans; 26.03.2020

Эти параметры четко упомянуты в документации Spark: --driver-class-path postgresql-9.4.1207.jar --jars postgresql-9.4.1207.jar

Ошибка, которую я делал, заключалась в том, что я упоминал эти параметры после jar-файла моего приложения.

Однако правильный способ - указать эти параметры сразу после spark-submit:

spark-submit --driver-class-path /somepath/project/mysql-connector-java-5.1.30-bin.jar --jars /somepath/project/mysql-connector-java-5.1.30-bin.jar --class com.package.MyClass target/scala-2.11/project_2.11-1.0.jar

person Ayush Vatsyayan    schedule 18.09.2017
comment
Вы спасаете жизнь. Спасибо - person biniam; 02.11.2017
comment
Я также создаю убер-банку со всем классом драйверов. Придется ли мне вручную вводить в jar-файл драйвера команду spark-submit? - person Abhi; 22.12.2017
comment
Я предполагаю, что если вы предоставили основную банку, тогда все банки внутри нее должны быть доступны в пути к классам. Вы пробовали такой подход? - person Ayush Vatsyayan; 08.01.2018
comment
Как это сделать правильно при подаче вакансии в EMR? - person Evan Zamir; 14.03.2018
comment
При использовании искровой оболочки в Windows вы можете использовать это, как показано ниже: spark-shell --driver-class-path C: \ Program Files \ Microsoft JDBC Driver 6.0 для SQL Server \ sqljdbc_6.0 \ enu \ jre8 \ sqljdbc42.jar --jars C: \ Program Files \ Microsoft JDBC Driver 6.0 для SQL Server \ sqljdbc_6.0 \ enu \ jre8 \ sqljdbc42.jar - person Nikunj Kakadiya; 13.03.2019

И драйвер искры, и исполнитель нуждаются в драйвере mysql в пути к классу, поэтому укажите

spark.driver.extraClassPath = <path>/mysql-connector-java-5.1.36.jar
spark.executor.extraClassPath = <path>/mysql-connector-java-5.1.36.jar
person jozh    schedule 17.07.2015
comment
или SparkSession.builder.config('spark.driver.extraClassPath', '/path/to/mysqlconnector.jar').config('spark.executor.extraClassPath', '/path/to/mysqlconnector.jar').getOrCreate(). Если вы попробуете это ПОСЛЕ создания подобного сеанса (но без конфигураций для jar-файла соединителя MySQL), перезапустите контейнер Docker для всех-искровых ноутбуков, если вы используете искру через это, а затем повторите попытку создания искрового сеанса, включая операторы конфигурации. - person Sander Vanden Hautte; 17.05.2019

В Spark 2.2.0 проблема была исправлена ​​для меня путем добавления дополнительной информации о пути к классу для сеанса SparkSession в скрипте python:

    spark = SparkSession \
        .builder \
        .appName("Python Spark SQL basic example") \
        .config("spark.driver.extraClassPath", "/path/to/jdbc/driver/postgresql-42.1.4.jar") \
        .getOrCreate()

См. Официальную документацию https://spark.apache.org/docs/latest/configuration.html < / а>

В моем случае Spark запускается не из команды cli, а из структуры django https://www.djangoproject.com/

person 06userit    schedule 17.09.2017
comment
Есть идеи, сработает ли это при отправке работы в Amazon EMR? - person Evan Zamir; 14.03.2018

spark.driver.extraClassPath не работает в клиентском режиме:

Примечание. В клиентском режиме эту конфигурацию нельзя настраивать через SparkConf непосредственно в вашем приложении, поскольку в этот момент драйвер JVM уже запущен. Вместо этого установите это с помощью параметра командной строки --driver-class-path или в файле свойств по умолчанию.

Переменная env SPARK_CLASSPATH устарела в Spark 1.0+.

Сначала вы должны скопировать jar-файлы драйвера jdbc в каждый исполнитель по одному и тому же пути локальной файловой системы, а затем использовать следующие параметры в своем spark-submit:

--driver-class-path "driver_local_file_system_jdbc_driver1.jar:driver_local_file_system_jdbc_driver2.jar"
--class "spark.executor.extraClassPath=executors_local_file_system_jdbc_driver1.jar:executors_local_file_system_jdbc_driver2.jar"

Например, в случае TeraData вам понадобятся как terajdbc4.jar, так и tdgssconfig.jar.

В качестве альтернативы измените compute_classpath.sh на всех рабочих узлах, в документации Spark говорится:

Класс драйвера JDBC должен быть видим для первоначального загрузчика классов в клиентском сеансе и во всех исполнителях. Это связано с тем, что класс DriverManager Java выполняет проверку безопасности, в результате которой он игнорирует все драйверы, не видимые исходному загрузчику классов, когда он открывает соединение. Один из удобных способов сделать это - изменить compute_classpath.sh на всех рабочих узлах, чтобы включить файлы JAR вашего драйвера.

person Gianmario Spacagna    schedule 03.12.2015

Для решения вашей проблемы существует простой Java-трюк. Вы должны указать Class.forName() экземпляр. Например:

 val customers: RDD[(Int, String)] = new JdbcRDD(sc, () => {
       Class.forName("com.mysql.jdbc.Driver")
       DriverManager.getConnection(jdbcUrl)
      },
      "SELECT id, name from customer WHERE ? < id and id <= ?" ,
      0, range, partitions, r => (r.getInt(1), r.getString(2)))

Ознакомьтесь с документами.

person Nikita    schedule 11.04.2015
comment
В Scala я использовал: new JdbcRDD (sc, () = ›{Class.forName (driverName) .newInstance; DriverManager.getConnection (url, user, password)}, SELECT * FROM stats_20151230, 0, 0, 1) Спасибо! - person beloblotskiy; 05.01.2016

Простой и легкий способ - скопировать "mysql-connector-java-5.1.47.jar" в каталог "spark-2.4.3 \ jars \".

person Roman Dubyk    schedule 29.05.2019

У меня была такая же проблема с запуском заданий в кластере Mesos в кластерном режиме.

Чтобы использовать драйвер JDBC, необходимо добавить зависимость к системному пути к классам, а не к пути к классам фреймворка. Я только нашел способ сделать это, добавив зависимость в файл spark-defaults.conf в каждом экземпляре кластера.

Добавляемые свойства: spark.driver.extraClassPath и spark.executor.extraClassPath, а путь должен быть в локальной файловой системе.

person Daniel Carroza    schedule 18.10.2016
comment
Я пробовал все решения здесь, ничего не работает, у меня не появляется подходящая ошибка драйвера. идеи? - person thebeancounter; 27.08.2017

Я добавляю файл jar в SPARK_CLASSPATH в spark-env.sh, он работает.

export SPARK_CLASSPATH=$SPARK_CLASSPATH:/local/spark-1.6.3-bin-hadoop2.6/lib/mysql-connector-java-5.1.40-bin.jar
person Robin Wang    schedule 22.11.2016

Я столкнулся с той же проблемой, когда пытался запустить команду spark-shell со своего компьютера с Windows. Путь, который вы передаете для местоположения драйвера, а также для используемой банки, должен быть в двойных кавычках, иначе он будет неправильно истолкован, и вы не получите точный результат, который вам нужен.

вам также придется установить драйвер JDBC для SQL-сервера по ссылке: Драйвер JDBC

Я использовал приведенную ниже команду, чтобы это нормально работало для меня на моем компьютере с Windows:

spark-shell --driver-class-path "C: \ Program Files \ Microsoft JDBC Driver 6.0 для SQL Server \ sqljdbc_6.0 \ enu \ jre8 \ sqljdbc42.jar" --jars "C: \ Program Files \ Драйвер Microsoft JDBC 6.0 для SQL Server \ sqljdbc_6.0 \ enu \ jre8 \ sqljdbc42.jar "

person Nikunj Kakadiya    schedule 13.03.2019
comment
Не могли бы вы изменить изображение ссылки, чтобы она действительно была ссылкой на изображение? Достаточно просто вставить URL - изображения вообще не нужны. :) - person Wai Ha Lee; 13.03.2019