2016-03-31 3 views
2

Мне нужно прочитать из базы данных postgres sql в pyspark. Я знаю, что это было задано до here, here и во многих других местах, однако решения там либо используют банку в локальном каталоге, либо копируют его всем рабочим вручную.Работа с jdbc jar в pyspark

Я загрузил банку postgresql-9.4.1208 и поместил ее в/tmp/jars. Затем я приступил к называть pyspark с --jars и --driver-класса тропу переключатели:

pyspark --master yarn --jars /tmp/jars/postgresql-9.4.1208.jar --driver-class-path /tmp/jars/postgresql-9.4.1208.jar 

Внутри pyspark я сделал:

df = sqlContext.read.format("jdbc").options(url="jdbc:postgresql://ip_address:port/db_name?user=myuser&password=mypasswd", dbtable="table_name").load() 
df.count() 

Однако при использовании --jars и - водитель-класс путь работал отлично для банок, которые я создал, он не для JDBC и я получил исключение из рабочих:

java.lang.IllegalStateException: Did not find registered driver with class org.postgresql.Driver 

Если я копирую банку вручную для всех работников и добавить --conf spark.executor. extraClassPath и --conf spark.driver.extr aClassPath, он работает (с той же банкой). documentation btw предлагает использовать SPARK_CLASSPATH, который устарел, фактически добавляет эти два переключателя (но имеет побочный эффект предотвращения добавления ДРУГИХ банок с параметром --jars, который мне нужно сделать)

Так что мой вопрос: что особенного драйвер jdbc, который делает его неработоспособным и как его можно добавить, без необходимости вручную копировать его всем работникам.

Update:

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

Проблема в том, что я не могу найти computer_classpath.sh и не понимаю, что означает начальный загрузчик классов.

Я нашел this, который в основном объясняет, что это нужно делать локально. Я также нашел this, который в основном говорит, что есть исправление, но оно еще не доступно в версии 1.6.1.

ответ

4

Я нашел решение, которое работает (не знаю, является ли он лучшим, поэтому не стесняйтесь продолжать комментирование). Очевидно, если я добавлю вариант: driver = "org.postgresql.Driver", это работает правильно. то есть моя полная линия (внутри pyspark) является:

df = sqlContext.read.format("jdbc").options(url="jdbc:postgresql://ip_address:port/db_name?user=myuser&password=mypasswd", dbtable="table_name",driver="org.postgresql.Driver").load() 
df.count() 

Другое дело: Если вы уже используете толстую банку самостоятельно (я в моем полном приложении), то все, что вам нужно сделать, это добавить драйвер JDBC в файл пом как таковой:

<dependency> 
     <groupId>org.postgresql</groupId> 
     <artifactId>postgresql</artifactId> 
     <version>9.4.1208</version> 
    </dependency> 

и тогда вам не придется добавить драйвер в отдельную банку, просто использовать банку с зависимостями.

+1

Это именно« официальное »обходное решение для этой регрессии, которое, как представляется, относится к Spark 1.6.1, как описано в ** SPARK-14204 ** c/o Kevin McHale https://issues.apache.org/jira/browse/SPARK-14204 –

+0

Мне очень жаль, что я не понял, как это работает, поскольку я не могу получить Java-код, который не является драйвером JDBC для загрузки. На самом деле, если я попытаюсь получить класс драйвера из py4j, он сообщает мне, что класс не найден. Используют ли драйверы JDBC другой шлюз py4j? –

0

В какой версии документации вы смотрите? Похоже compute-classpath.sh осуждался некоторое время назад, - как искры 1.3.1:

$ unzip -l spark-1.3.1.zip | egrep '\.sh' | egrep classpa 
6592 2015-04-11 00:04 spark-1.3.1/bin/compute-classpath.sh 

$ unzip -l spark-1.4.0.zip | egrep '\.sh' | egrep classpa 

ничего не производит.

Я думаю, вы должны использовать load-spark-env.sh, чтобы установить: путь к классам

$/opt/spark-1.6.0-bin-hadoop2.6/bin/load-spark-env.sh 

и вам нужно установить SPARK_CLASSPATH в файле $SPARK_HOME/conf/spark-env.sh (который вы будете копировать из файл шаблона $SPARK_HOME/conf/spark-env.sh.template).

+0

, как вы можете видеть из моей ссылки (повторяется здесь: http://spark.apache.org/docs/latest/sql-programming-guide.html#jdbc-to-other-databases) Я посмотрел последнюю документацию (см. раздел «Поиск и устранение неисправностей»). Весь раздел имеет устаревший элемент (как я уже сказал, он все еще имеет SPARK_CLASSPATH, который также устарел) –

+0

Вы правы. Я могу успешно вернуть результаты - хотя и работает пряжа на localhost: '' '>>> df = sqlContext.read.format (" jdbc ") .options (url =" jdbc: postgresql: // localhost/myprojects? user = XXX & password = XXX ", dbtable =" django_session "). load() >>> df.count ' '' '' '>>> df.count() 4''' – femibyte

0

Я думаю, что это еще одно проявление проблемы, описанной и исправленной здесь: https://github.com/apache/spark/pull/12000. Я создал это исправление 3 недели назад, и на нем не было никакого движения. Может быть, если другие также выражают тот факт, что они были затронуты им, это может помочь?

+0

Интересно, почему кто-то сделал -1, так как ** вы правильно сообщаете, что это регрессия Spark ** –

Смежные вопросы