#apache-spark #pyspark #amazon-emr
#apache-spark #pyspark #amazon-emr
Вопрос:
Раньше мы считывали данные в Spark 2.3, используя блоки данных со следующим сегментом кода инициализации Spark-Shell :
spark-shell --jars RedshiftJDBC42-1.2.10.1009.jar --packages com.databricks:spark-redshift_2.11:3.0.0-preview1,com.databricks:spark-avro_2.11:3.2.0
и затем
val url = "jdbc:redshift://cluster-link?user=usernameamp;password=password"
val queryFinal = "select count(*) as cnt from table1"
val df = spark.read.format("com.databricks.spark.redshift").option("url", url).option("tempdir", "s3n://temp-bucket/").option("query",queryFinal).option("forward_spark_s3_credentials", "true").load().cache
С недавним обновлением Spark 2.4 мы не можем этого сделать и получаем следующее исключение
java.lang.AbstractMethodError: com.databricks.spark.redshift.RedshiftFileFormat.supportDataType(Lorg/apache/spark/sql/types/DataType;Z)Z
at org.apache.spark.sql.execution.datasources.DataSourceUtils$anonfun$verifySchema$1.apply(DataSourceUtils.scala:48)
at org.apache.spark.sql.execution.datasources.DataSourceUtils$anonfun$verifySchema$1.apply(DataSourceUtils.scala:47)
at scala.collection.Iterator$class.foreach(Iterator.scala:891)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at org.apache.spark.sql.types.StructType.foreach(StructType.scala:99)
at org.apache.spark.sql.execution.datasources.DataSourceUtils$.verifySchema(DataSourceUtils.scala:47)
at org.apache.spark.sql.execution.datasources.DataSourceUtils$.verifyReadSchema(DataSourceUtils.scala:39)
at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:400)
at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:223)
at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:211)
at com.databricks.spark.redshift.RedshiftRelation.buildScan(RedshiftRelation.scala:168)
at org.apache.spark.sql.execution.datasources.DataSourceStrategy$anonfun$10.apply(DataSourceStrategy.scala:293)
at org.apache.spark.sql.execution.datasources.DataSourceStrategy$anonfun$10.apply(DataSourceStrategy.scala:293)
at org.apache.spark.sql.execution.datasources.DataSourceStrategy$anonfun$pruneFilterProject$1.apply(DataSourceStrategy.scala:326)
at org.apache.spark.sql.execution.datasources.DataSourceStrategy$anonfun$pruneFilterProject$1.apply(DataSourceStrategy.scala:325)
at org.apache.spark.sql.execution.datasources.DataSourceStrategy.pruneFilterProjectRaw(DataSourceStrategy.scala:403)
at org.apache.spark.sql.execution.datasources.DataSourceStrategy.pruneFilterProject(DataSourceStrategy.scala:321)
at org.apache.spark.sql.execution.datasources.DataSourceStrategy.apply(DataSourceStrategy.scala:289)
at org.apache.spark.sql.catalyst.planning.QueryPlanner$anonfun$1.apply(QueryPlanner.scala:63)
at org.apache.spark.sql.catalyst.planning.QueryPlanner$anonfun$1.apply(QueryPlanner.scala:63)
at scala.collection.Iterator$anon$12.nextCur(Iterator.scala:435)
at scala.collection.Iterator$anon$12.hasNext(Iterator.scala:441)
at scala.collection.Iterator$anon$12.hasNext(Iterator.scala:440)
at org.apache.spark.sql.catalyst.planning.QueryPlanner.plan(QueryPlanner.scala:93)
at org.apache.spark.sql.catalyst.planning.QueryPlanner$anonfun$2$anonfun$apply$2.apply(QueryPlanner.scala:78)
at org.apache.spark.sql.catalyst.planning.QueryPlanner$anonfun$2$anonfun$apply$2.apply(QueryPlanner.scala:75)
at scala.collection.TraversableOnce$anonfun$foldLeft$1.apply(TraversableOnce.scala:157)
at scala.collection.TraversableOnce$anonfun$foldLeft$1.apply(TraversableOnce.scala:157)
at scala.collection.Iterator$class.foreach(Iterator.scala:891)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
at scala.collection.TraversableOnce$class.foldLeft(TraversableOnce.scala:157)
at scala.collection.AbstractIterator.foldLeft(Iterator.scala:1334)
at org.apache.spark.sql.catalyst.planning.QueryPlanner$anonfun$2.apply(QueryPlanner.scala:75)
at org.apache.spark.sql.catalyst.planning.QueryPlanner$anonfun$2.apply(QueryPlanner.scala:67)
at scala.collection.Iterator$anon$12.nextCur(Iterator.scala:435)
at scala.collection.Iterator$anon$12.hasNext(Iterator.scala:441)
at org.apache.spark.sql.catalyst.planning.QueryPlanner.plan(QueryPlanner.scala:93)
at org.apache.spark.sql.execution.QueryExecution.sparkPlan$lzycompute(QueryExecution.scala:72)
at org.apache.spark.sql.execution.QueryExecution.sparkPlan(QueryExecution.scala:68)
at org.apache.spark.sql.execution.QueryExecution.executedPlan$lzycompute(QueryExecution.scala:77)
at org.apache.spark.sql.execution.QueryExecution.executedPlan(QueryExecution.scala:77)
at org.apache.spark.sql.Dataset.withAction(Dataset.scala:3360)
at org.apache.spark.sql.Dataset.head(Dataset.scala:2545)
at org.apache.spark.sql.Dataset.take(Dataset.scala:2759)
at org.apache.spark.sql.Dataset.getRows(Dataset.scala:255)
at org.apache.spark.sql.Dataset.showString(Dataset.scala:292)
at org.apache.spark.sql.Dataset.show(Dataset.scala:746)
at org.apache.spark.sql.Dataset.show(Dataset.scala:705)
at org.apache.spark.sql.Dataset.show(Dataset.scala:714)
Я проверил онлайн-форумы и узнал, что Spark 2.4 добавил встроенный исходный код Avro, и именно по этой причине, используя databricks, мы не можем десериализовать данные.
Я попробовал два способа:
- Значение
spark.sql.legacy.replaceDatabricksSparkAvro.enabled
true
https://spark.apache.org/docs/latest/sql-data-sources-avro.html
Исключение здесь осталось прежним.
- Использование URL-соединения JDBC https://spark.apache.org/docs/latest/sql-data-sources-jdbc.html Я получаю тайм-аут для подключения.
Кто-нибудь знает, есть ли решение для этого? Это будет действительно полезно.
Ответ №1:
Как сказано в этом выпуске databricks spark-redshift connector, библиотека больше не поддерживается как отдельный проект, и, следовательно, она не поддерживает Spark 2.4.x
Если вы хотите продолжать использовать Redshift с Spark 2.4.x, есть альтернатива: форк Udemy. Для этого вам необходимо добавить зависимости Avro ( "org.apache.spark" %% "spark-avro"
включенные в Spark с версии 2.4.0) как «предоставленные» в вашем файле зависимостей и добавить опцию --packages org.apache.spark:spark-avro_2.12:2.4.3
в команду spark-submit, как описано в документации Avro.