本文介紹了為什么在Spark SQL&;寫入之后,&;t Impala可以讀取鑲木地板文件?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
Spark解釋鑲木地板柱子的方式有一些問題。
我有一個具有確認架構(df.schema()方法)的Oracle源代碼:
root
|-- LM_PERSON_ID: decimal(15,0) (nullable = true)
|-- LM_BIRTHDATE: timestamp (nullable = true)
|-- LM_COMM_METHOD: string (nullable = true)
|-- LM_SOURCE_IND: string (nullable = true)
|-- DATASET_ID: decimal(38,0) (nullable = true)
|-- RECORD_ID: decimal(38,0) (nullable = true)
然后保存為parquet-df.write().parket()方法,并帶有相應的消息類型(由Spark確定):
message spark_schema {
optional int64 LM_PERSON_ID (DECIMAL(15,0));
optional int96 LM_BIRTHDATE;
optional binary LM_COMM_METHOD (UTF8);
optional binary LM_SOURCE_IND (UTF8);
optional fixed_len_byte_array(16) DATASET_ID (DECIMAL(38,0));
optional fixed_len_byte_array(16) RECORD_ID (DECIMAL(38,0));
}
然后,我的應用程序使用用于類型轉換的HashMap生成表DDL,例如:
CREATE EXTERNAL TABLE IF NOT EXISTS
ELM_PS_LM_PERSON (
LM_PERSON_ID DECIMAL(15,0)
,LM_BIRTHDATE TIMESTAMP
,LM_COMM_METHOD STRING
,LM_SOURCE_IND STRING
,DATASET_ID DECIMAL(38,0)
,RECORD_ID DECIMAL(38,0)
) PARTITIONED BY (edi_business_day STRING) STORED AS PARQUET LOCATION '<PATH>'
我的問題是,Impala將無法讀取該表,因為它不接受LM_PERSON_ID作為十進制字段。如果此列設置為BIGINT,則表將僅讀取拼圖文件。
Query 8d437faf6323f0bb:b7ba295d028c8fbe: 0% Complete (0 out of 1)
File 'hdfs:dev/ELM/ELM_PS_LM_PERSON/part-00000-fcdbd3a5-9c93-490e-a124-c2a327a17a17.snappy.parquet' has an incompatible Parquet schema for column 'rbdshid1.elm_ps_lm_person_2.lm_person_id'.
Column type: DOUBLE, Parquet schema:
optional int64 LM_PERSON_ID [i:0 d:1 r:0]
如何知道何時用Decimal字段替換BIGINT?
拼接消息類型已記錄,但無法訪問?
兩個十進制字段轉換為FIXED_LEN_BYTE_ARRAY(16),LM_PERSON_ID轉換為int64
我能想到的唯一解決辦法是創建表,測試它是否返回,如果不返回,則逐個刪除小數字段并將其替換為BIGINT,每次都進行測試。
我在這里錯過了什么?我可以強制拼圖文件使用十進制架構嗎?
推薦答案
來自ApacheSpark官方文檔中Parquet Files的Configuration部分:
spark.sql.parquet.writeLegacyFormat(默認:
false
)如果為True,則數據將以Spark 1.4及更早版本的方式寫入。例如,十進制值將以ApacheParquet的固定長度字節數組格式寫入,其他系統(如ApacheHave和ApacheImpala)也使用這種格式。如果為False,則將使用拼圖中較新的格式。例如,小數將以基于整型的格式寫入。如果拼圖輸出用于不支持此較新格式的系統,請設置為TRUE。
公文更新前的答復
非常類似的SPARK-20297 Parquet Decimal(12,2) written by Spark is unreadable by Hive and Impala最近(20/Apr/17 01:59)被解決為不是問題。
主要是使用spark.sql.parquet.writeLegacyFormat
屬性并以遺留格式編寫拼圖元數據(我在Configuration下的官方文檔中沒有描述,并且在SPARK-20937中報告為改進)。
啟用spak.sql.parquet.WriteLegacyFormat時,Spark寫入的數據可由配置單元和Impala讀取。
它確實遵循較新的標準-https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#decimal,我錯過了文檔。
那不就是黑斑羚或蜂巢里的蟲子了嗎?int32/int64選項出現在DECIMAL規范的原始版本中,只是它們沒有被廣泛實現:https://github.com/Parquet/parquet-format/commit/b2836e591da8216cfca47075baee2c9a7b0b9289。因此,它不是新/舊版本的東西,它只是許多系統沒有實現的替代表示法。
這本SPARK-10400也可能是非常有用的讀物(關于spark.sql.parquet.writeLegacyFormat
屬性的歷史):
我們在致力于實現SPARK-6777中的向后兼容規則時,引入了SQL選項”spk.sql.parquet.postParquetFormatSpec”。它指示我們是應該使用Spark 1.4及更早版本采用的傳統拼圖格式,還是應該使用拼圖格式規范中定義的標準格式。然而,這個選項的名稱有點令人困惑,因為它并不是我們不應該遵循規范的超直觀的原因。最好將其重命名為”spk.sql.parquet.WriteLegacyFormat”,并反轉其缺省值(它們具有相反的含義)。請注意,此選項不是”Public”(isPublic為False)。
這篇關于為什么在Spark SQL&;寫入之后,&;t Impala可以讀取鑲木地板文件?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,