2017-01-26 10 views
3

Искры версии 1.6.0.SparkSQL ключ не найден: шкала

Я пытаюсь выполнить простой SQL-запрос к удаленному блоку Oracle 11g с помощью Spark SQL.

Конечно, драйвер ojdbc добавлен в путь к классам и пинг в БД также в порядке.

SparkConf conf = new SparkConf().setAppName(APP_NAME).setMaster("yarn-client"); 
JavaSparkContext jsc = new JavaSparkContext(conf); 
SqlContext sqlContext = new SqlContext(jsc); 

Map<String, String> connectionProperties = new HashMap<>(); 
connectionProperties.put("user", username); 
connectionProperties.put("password", password); 
connectionProperties.put("url", url); 
connectionProperties.put("dbtable", "(SELECT * FROM tableName)"); 
connectionProperties.put("driver", "oracle.jdbc.OracleDriver"); 

DataFrame result = sqlContext.read().format("jdbc").options(connectionProperties).load(); 

Ошибка возникает в последней строке в .load() метода.

Приведенное StackTrace является:

Exception in thread "main" java.util.NoSuchElementException: key not found: scale 
    at scala.collection.MapLike$class.default(MapLike.scala:228) 
    at scala.collection.AbstractMap.default(Map.scala:58) 
    at scala.collection.MapLike$class.apply(MapLike.scala:141) 
    at scala.collection.AbstractMap.apply(Map.scala:58) 
    at org.apache.spark.sql.types.Metadata.get(Metadata.scala:108) 
    at org.apache.spark.sql.types.Metadata.getLong(Metadata.scala:51) 
    at org.apache.spark.sql.jdbc.OracleDialect$.getCatalystType(OracleDialect.scala:33) 
    at org.apache.spark.sql.execution.datasources.jdbc.JDBCRDD$.resolveTable(JDBCRDD.scala:140) 
    at org.apache.spark.sql.execution.datasources.jdbc.JDBCRelation.<init>(JDBCRelation.scala:91) 
    at org.apache.spark.sql.execution.datasources.jdbc.DefaultSource.createRelation(DefaultSource.scala:57) 
    at org.apache.spark.sql.execution.datasources.ResolvedDataSource$.apply(ResolvedDataSource.scala:158) 
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:119) 
    at myapp.dfComparator.entity.OriginalSourceTable.load(OriginalSourceTable.java:74) 
    at myapp.dfComparator.Program.main(Program.java:74) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731) 
    at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181) 
    at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206) 
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121) 
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala) 

У меня нет ума, что это неправильно.

EDIT 01/27/2017

Дополнительная информация:

Hadoop версия 2.6.0-cdh.5.8.3

Спарк версия 1.6.0 с Scala версии 2.10. 5

Я пытаюсь воспроизвести код, указанный выше в Скале и выполнить его с помощью spark-shell:

val jdbcDF = sqlContext.read.format("jdbc").options(
Map("url" -> "jdbc:oracle:thin:system/[email protected]:1521:orcl", 
"dbtable"-> "schema_name.table_name", 
"driver"-> "oracle.jdbc.OracleDriver", 
"username" -> "user", 
"password" -> "pwd")).load() 

Результат этого кода является StackTrace похож:

java.util.NoSuchElementException: key not found: scale 
    at scala.collection.MapLike$class.default(MapLike.scala:228) 
    at scala.collection.AbstractMap.default(Map.scala:58) 
    at scala.collection.MapLike$class.apply(MapLike.scala:141) 
    at scala.collection.AbstractMap.apply(Map.scala:58) 
    at org.apache.spark.sql.types.Metadata.get(Metadata.scala:108) 
    at org.apache.spark.sql.types.Metadata.getLong(Metadata.scala:51) 
    at org.apache.spark.sql.jdbc.OracleDialect$.getCatalystType(OracleDialect.scala:33) 
    at org.apache.spark.sql.execution.datasources.jdbc.JDBCRDD$.resolveTable(JDBCRDD.scala:140) 
    at org.apache.spark.sql.execution.datasources.jdbc.JDBCRelation.<init>(JDBCRelation.scala:91) 
    at org.apache.spark.sql.execution.datasources.jdbc.DefaultSource.createRelation(DefaultSource.scala:57) 
    at org.apache.spark.sql.execution.datasources.ResolvedDataSource$.apply(ResolvedDataSource.scala:158) 
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:119) 
    at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:25) 
    at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:30) 
    at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:32) 
    at $iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:34) 
    at $iwC$$iwC$$iwC$$iwC.<init>(<console>:36) 
    at $iwC$$iwC$$iwC.<init>(<console>:38) 
    at $iwC$$iwC.<init>(<console>:40) 
    at $iwC.<init>(<console>:42) 
    at <init>(<console>:44) 
    at .<init>(<console>:48) 
    at .<clinit>(<console>) 
    at .<init>(<console>:7) 
    at .<clinit>(<console>) 
    at $print(<console>) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.spark.repl.SparkIMain$ReadEvalPrint.call(SparkIMain.scala:1045) 
    at org.apache.spark.repl.SparkIMain$Request.loadAndRun(SparkIMain.scala:1326) 
    at org.apache.spark.repl.SparkIMain.loadAndRunReq$1(SparkIMain.scala:821) 
    at org.apache.spark.repl.SparkIMain.interpret(SparkIMain.scala:852) 
    at org.apache.spark.repl.SparkIMain.interpret(SparkIMain.scala:800) 
    at org.apache.spark.repl.SparkILoop.reallyInterpret$1(SparkILoop.scala:857) 
    at org.apache.spark.repl.SparkILoop.interpretStartingWith(SparkILoop.scala:902) 
    at org.apache.spark.repl.SparkILoop.command(SparkILoop.scala:814) 
    at org.apache.spark.repl.SparkILoop.processLine$1(SparkILoop.scala:657) 
    at org.apache.spark.repl.SparkILoop.innerLoop$1(SparkILoop.scala:665) 
    at org.apache.spark.repl.SparkILoop.org$apache$spark$repl$SparkILoop$$loop(SparkILoop.scala:670) 
    at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply$mcZ$sp(SparkILoop.scala:997) 
    at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply(SparkILoop.scala:945) 
    at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply(SparkILoop.scala:945) 
    at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135) 
    at org.apache.spark.repl.SparkILoop.org$apache$spark$repl$SparkILoop$$process(SparkILoop.scala:945) 
    at org.apache.spark.repl.SparkILoop.process(SparkILoop.scala:1064) 
    at org.apache.spark.repl.Main$.main(Main.scala:31) 
    at org.apache.spark.repl.Main.main(Main.scala) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731) 
    at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181) 
    at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206) 
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121) 
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala) 

Итак, у меня есть сильное ощущение, что есть некоторые ошибки в конфигурации искры или (и) Hadoop.

EDIT 02/01/2017

Я исследую, что такая задача возникает только в том случае, если тип столбца в таблице оракула NUMBER. Например, если я бросил id столбец (тип которого NUMBER) для VARCHAR в отборном заявлении, то все будет работать нормально:

val jdbcDF = sqlContext.read.format("jdbc").options(
    Map("url" -> "jdbc:oracle:thin:system/[email protected]:1521:orcl", 
    "dbtable"-> "(SELECT CAST(id AS varchar(3))) FROM tableName", 
    "driver"-> "oracle.jdbc.OracleDriver", 
    "username" -> "user", 
    "password" -> "pwd")).load() 

Более детали - staktrace показать нам, что проблема в том, появляется org.apache.spark.sql.types.Metadata.get метода , Исследуя этот метод от sources, мы можем видеть (или предполагать), что в случае NUMBER типа он пытается передать его Long и не может найти его масштаб.

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

ответ

1

В это время я получил ответ от Cloudera, что в CDH 5.8.3 с Spark 1.6 это известная проблема, которая разрешена в версии Spark 2.0.

Для преодоления этой проблемы у нас есть 3 варианта:

  • В окне Выбор запроса CASTлюбой числовой типа для VARCHAR.Вместо CAST мы также можем использовать TO_CHAR функция.

  • Для загрузки данных используйте RDD/JavaRDD (вместо Dataframe) и после этого
    преобразовать его в Dataframes (что гораздо быстрее)

  • Использование CDH 5.9.x