Работа с JDBC jar в pyspark
Мне нужно прочитать из базы данных postgres sql в pyspark. Я знаю, что об этом уже спрашивали раньше, например, здесь, здесь и во многих других местах, однако, решения там либо используют jar в локальном рабочем каталоге, либо копируют его для всех рабочих вручную.
Я загрузил postgresql-9.4.1208 jar и поместил его в /tmp/jars. Затем я перешел к вызову pyspark с переключателями-jars и-driver-class-path:
pyspark --master yarn --jars /tmp/jars/postgresql-9.4.1208.jar --driver-class-path /tmp/jars/postgresql-9.4.1208.jar
Внутри пыспарка я так и сделал.:
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 и -- driver-class-path отлично работало для jars, которые я создал, это не удалось для jdbc, и я получил исключение от рабочих:
java.lang.IllegalStateException: Did not find registered driver with class org.postgresql.Driver
Если я скопирую банку вручную для всех рабочих и добавлю --conf spark.исполнитель.экстраклассовая дорожка и ... Искра конф.водитель.extraClassPath, он действительно работает (с той же банкой). Документация btw предлагает использовать SPARK_CLASSPATH, который является устаревшим, фактически добавляет эти два переключателя (но имеет побочный эффект предотвращения добавление других банок с опцией --jars, что мне нужно сделать)
Итак, мой вопрос: Что особенного в драйвере jdbc, который делает его неработающим, и как я могу добавить его без необходимости вручную копировать его всем работникам.
Обновление:
Я еще немного поискал и нашел это в документации: "Класс драйвера JDBC должен быть виден загрузчику исходного класса в сеансе клиента и на всех исполнителях. Это происходит потому, что класс DriverManager Java делает проверка безопасности, которая приводит к тому, что он игнорирует все драйверы, не видимые загрузчику класса primordial, когда один идет, чтобы открыть соединение. Один из удобных способов сделать это-изменить compute_classpath.sh на всех рабочих узлах включить свой драйвер JARs.".
Проблема в том, что я, кажется, не могу найти computer_classpath.sh я также не понимаю, что означает изначальный загрузчик классов.
Я нашел это, которое в основном объясняет, что это должно быть сделано локально. Я также нашел это , который в основном говорит, что есть исправление, но оно еще не доступно в версии 1.6.1.
3 ответа:
Я нашел решение, которое работает (не знаю, является ли оно лучшим, поэтому не стесняйтесь продолжать комментировать). Видимо, если я добавлю опцию: driver= " org.в PostgreSQL.Водитель", это работает правильно. то есть моя полная строка (внутри 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()
Еще одна вещь: если вы уже используете свой собственный fat jar (я в своем полном приложении) , то все, что вам нужно сделать, это добавить драйвер jdbc в ваш POM-файл как таковой:
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4.1208</version> </dependency>
И тогда вам не нужно добавлять драйвер как отдельную банку., просто используйте банку с зависимостями.
Какую версию документации вы смотрите ? Похоже, что
compute-classpath.sh
был устаревшим некоторое время назад-по состоянию на Spark 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
).
Я думаю, что это еще одно проявление проблемы, описанной и зафиксированной здесь: https://github.com/apache/spark/pull/12000 . я написал это исправление 3 недели назад, и в нем не было никакого движения. Может быть, если другие также выразят тот факт, что они были затронуты этим, это может помочь?