本文介紹了為什么在Spark SQL&;寫入之后,&;t Impala可以讀取鑲木地板文件?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
Spark解釋鑲木地板柱子的方式有一些問題。
我有一個具有確認(rèn)架構(gòu)(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()方法,并帶有相應(yīng)的消息類型(由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));
}
然后,我的應(yīng)用程序使用用于類型轉(zhuǎn)換的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將無法讀取該表,因?yàn)樗唤邮躄M_PERSON_ID作為十進(jìn)制字段。如果此列設(shè)置為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?
拼接消息類型已記錄,但無法訪問?
兩個十進(jìn)制字段轉(zhuǎn)換為FIXED_LEN_BYTE_ARRAY(16),LM_PERSON_ID轉(zhuǎn)換為int64
我能想到的唯一解決辦法是創(chuàng)建表,測試它是否返回,如果不返回,則逐個刪除小數(shù)字段并將其替換為BIGINT,每次都進(jìn)行測試。
我在這里錯過了什么?我可以強(qiáng)制拼圖文件使用十進(jìn)制架構(gòu)嗎?
推薦答案
來自ApacheSpark官方文檔中Parquet Files的Configuration部分:
spark.sql.parquet.writeLegacyFormat(默認(rèn):
false
)如果為True,則數(shù)據(jù)將以Spark 1.4及更早版本的方式寫入。例如,十進(jìn)制值將以ApacheParquet的固定長度字節(jié)數(shù)組格式寫入,其他系統(tǒng)(如ApacheHave和ApacheImpala)也使用這種格式。如果為False,則將使用拼圖中較新的格式。例如,小數(shù)將以基于整型的格式寫入。如果拼圖輸出用于不支持此較新格式的系統(tǒng),請?jiān)O(shè)置為TRUE。
公文更新前的答復(fù)
非常類似的SPARK-20297 Parquet Decimal(12,2) written by Spark is unreadable by Hive and Impala最近(20/Apr/17 01:59)被解決為不是問題。
主要是使用spark.sql.parquet.writeLegacyFormat
屬性并以遺留格式編寫拼圖元數(shù)據(jù)(我在Configuration下的官方文檔中沒有描述,并且在SPARK-20937中報(bào)告為改進(jìn))。
啟用spak.sql.parquet.WriteLegacyFormat時,Spark寫入的數(shù)據(jù)可由配置單元和Impala讀取。
它確實(shí)遵循較新的標(biāo)準(zhǔn)-https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#decimal,我錯過了文檔。
那不就是黑斑羚或蜂巢里的蟲子了嗎?int32/int64選項(xiàng)出現(xiàn)在DECIMAL規(guī)范的原始版本中,只是它們沒有被廣泛實(shí)現(xiàn):https://github.com/Parquet/parquet-format/commit/b2836e591da8216cfca47075baee2c9a7b0b9289。因此,它不是新/舊版本的東西,它只是許多系統(tǒng)沒有實(shí)現(xiàn)的替代表示法。
這本SPARK-10400也可能是非常有用的讀物(關(guān)于spark.sql.parquet.writeLegacyFormat
屬性的歷史):
我們在致力于實(shí)現(xiàn)SPARK-6777中的向后兼容規(guī)則時,引入了SQL選項(xiàng)”spk.sql.parquet.postParquetFormatSpec”。它指示我們是應(yīng)該使用Spark 1.4及更早版本采用的傳統(tǒng)拼圖格式,還是應(yīng)該使用拼圖格式規(guī)范中定義的標(biāo)準(zhǔn)格式。然而,這個選項(xiàng)的名稱有點(diǎn)令人困惑,因?yàn)樗⒉皇俏覀儾粦?yīng)該遵循規(guī)范的超直觀的原因。最好將其重命名為”spk.sql.parquet.WriteLegacyFormat”,并反轉(zhuǎn)其缺省值(它們具有相反的含義)。請注意,此選項(xiàng)不是”Public”(isPublic為False)。
這篇關(guān)于為什么在Spark SQL&;寫入之后,&;t Impala可以讀取鑲木地板文件?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,