при попытке использовать spark 2.3 на HDP 3.1 для записи в таблицу Hive без соединителя хранилища непосредственно в схему кустов с использованием:
spark-shell --driver-memory 16g --master local[3] --conf spark.hadoop.metastore.catalog.default=hive
val df = Seq(1,2,3,4).toDF
spark.sql("create database foo")
df.write.saveAsTable("foo.my_table_01")
завершается неудачно с:
Table foo.my_table_01 failed strict managed table checks due to the following reason: Table is marked as a managed table but is not transactional
, ноa:
val df = Seq(1,2,3,4).toDF.withColumn("part", col("value"))
df.write.partitionBy("part").option("compression", "zlib").mode(SaveMode.Overwrite).format("orc").saveAsTable("foo.my_table_02")
Spark с spark.sql("select * from foo.my_table_02").show
работает просто отлично. Теперь перейдем к Hive / beeline:
0: jdbc:hive2://hostname:2181/> select * from my_table_02;
Error: java.io.IOException: java.lang.IllegalArgumentException: bucketId out of range: -1 (state=,code=0)
A
describe extended my_table_02;
возвращает
+-----------------------------+----------------------------------------------------+----------+
| col_name | data_type | comment |
+-----------------------------+----------------------------------------------------+----------+
| value | int | |
| part | int | |
| | NULL | NULL |
| # Partition Information | NULL | NULL |
| # col_name | data_type | comment |
| part | int | |
| | NULL | NULL |
| Detailed Table Information | Table(tableName:my_table_02, dbName:foo, owner:hive/bd-sandbox.t-mobile.at@SANDBOX.MAGENTA.COM, createTime:1571201905, lastAccessTime:0, retention:0, sd:StorageDescriptor(cols:[FieldSchema(name:value, type:int, comment:null), FieldSchema(name:part, type:int, comment:null)], location:hdfs://bd-sandbox.t-mobile.at:8020/warehouse/tablespace/external/hive/foo.db/my_table_02, inputFormat:org.apache.hadoop.hive.ql.io.orc.OrcInputFormat, outputFormat:org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat, compressed:false, numBuckets:-1, serdeInfo:SerDeInfo(name:null, serializationLib:org.apache.hadoop.hive.ql.io.orc.OrcSerde, parameters:{path=hdfs://bd-sandbox.t-mobile.at:8020/warehouse/tablespace/external/hive/foo.db/my_table_02, compression=zlib, serialization.format=1}), bucketCols:[], sortCols:[], parameters:{}, skewedInfo:SkewedInfo(skewedColNames:[], skewedColValues:[], skewedColValueLocationMaps:{}), storedAsSubDirectories:false), partitionKeys:[FieldSchema(name:part, type:int, comment:null)], parameters:{numRows=0, rawDataSize=0, spark.sql.sources.schema.partCol.0=part, transient_lastDdlTime=1571201906, bucketing_version=2, spark.sql.create.version=2.3.2.3.1.0.0-78, totalSize=740, spark.sql.sources.schema.numPartCols=1, spark.sql.sources.schema.part.0={\"type\":\"struct\",\"fields\":[{\"name\":\"value\",\"type\":\"integer\",\"nullable\":true,\"metadata\":{}},{\"name\":\"part\",\"type\":\"integer\",\"nullable\":true,\"metadata\":{}}]}, numFiles=4, numPartitions=4, spark.sql.partitionProvider=catalog, spark.sql.sources.schema.numParts=1, spark.sql.sources.provider=orc, transactional=true}, viewOriginalText:null, viewExpandedText:null, tableType:MANAGED_TABLE, rewriteEnabled:false, catName:hive, ownerType:USER, writeId:-1) |
Как использовать spark для записи в улей без использованияконнектор хранилища , но все еще записываете в то же самое хранилище метаданных, которое позже можно прочитать с помощью улья? Насколько мне известно, внешние таблицы должны быть возможны (они не управляются, не ACID, не транзакционные), но я не уверен, как saveAsTable
сказать, как с ними обращаться.
edit
связанные с этим вопросы:
Может быть обходной путь, как https://github.com/qubole/spark-acid как https://docs.cloudera.com/HDPDocuments/HDP3/HDP-3.1.4/integrating-hive/content/hive_hivewarehouseconnector_for_handling_apache_spark_data.html но мне не нравится идея использовать больше клейкой ленты, где я еще не видел масштабных тестов производительности. Кроме того, это означает изменение всех существующих заданий на запуск.
Фактически Не удается сохранить таблицу в метасольве улья, HDP 3.0 сообщает о проблемах с большими фреймами данных и соединителем хранилища.
edit
Я только что нашел https://community.cloudera.com/t5/Support-Questions/Spark-hive-warehouse-connector-not-loading-data-when-using/td-p/243613
И:
execute () vs executeQuery ()
ExecuteQuery () всегда будет использоватьHiveserver2-интерактивный / LLAP, поскольку он использует быстрый протокол ARROW. Использование его, когда URL-адрес jdbc указывает на не-LLAP Hiveserver2, приведет к ошибке.
Execute () использует JDBC и не имеет этой зависимости от LLAP, но имеет встроенное ограничение для возврата только 1000 записейМаксимум. Но для большинства запросов (INSERT INTO ... SELECT, count, sum, medium) это не проблема.
Но не мешает ли это высокопроизводительной совместимости между кустом и искрой? Особенно, если для крупномасштабного ETL недостаточно узлов LLAP.
На самом деле это действительно так. Этот параметр можно настроить на https://github.com/hortonworks-spark/spark-llap/blob/26d164e62b45cfa1420d5d43cdef13d1d29bb877/src/main/java/com/hortonworks/spark/sql/hive/llap/HWConf.java#L39,, хотя я не уверен в влиянии на производительность увеличения этого значения