2017-03-09 36 views
0

我有一個AWS IoT規則將傳入的JSON發送到Kinesis Firehose。如何過濾進入AWS Hive表的多行JSON數據

從我的物聯網發佈的JSON數據是全部在一行上 - 例如:

{"count":4950, "dateTime8601": "2017-03-09T17:15:28.314Z"} 

在管理界面的IOT測試「測試」部分允許你發佈的消息,默認爲以下(注格式化多-line JSON):

{ 
    "message": "Hello from AWS IoT console" 
} 

我流的流水到S3,然後通過EMR轉換爲柱狀格式最終由雅典娜使用。

問題是,在轉換爲列格式時,Hive(特別是JSON SerDe)無法處理跨越多行的JSON對象。它會炸燬轉換,而不會轉換好的單行JSON記錄。

我的問題是

  • 你如何設置流水忽略多行JSON?
  • 如果不可能,如何告訴Hive在載入表之前刪除換行符,或者至少捕獲異常並嘗試繼續?

我已經開始嘗試定義蜂巢表時忽略畸形的JSON:

DROP TABLE site_sensor_data_raw; 
CREATE EXTERNAL TABLE site_sensor_data_raw (
count int,  
dateTime8601 timestamp 
) 
PARTITIONED BY(year int, month int, day int, hour int) 
ROW FORMAT serde 'org.apache.hive.hcatalog.data.JsonSerDe' 
with serdeproperties (
'ignore.malformed.json' = 'true', 
"timestamp.formats"="yyyy-MM-dd'T'HH:mm:ss.SSS'Z',millis" 
) 
LOCATION 's3://...'; 

這裏是我的全HQL,做轉換:

--Example of converting to OEX/columnar formats 
DROP TABLE site_sensor_data_raw; 
CREATE EXTERNAL TABLE site_sensor_data_raw (
    count int, 
    dateTime8601 timestamp 
) 
PARTITIONED BY(year int, month int, day int, hour int) 
ROW FORMAT serde 'org.apache.hive.hcatalog.data.JsonSerDe' 
with serdeproperties (
'ignore.malformed.json' = 'true', 
"timestamp.formats"="yyyy-MM-dd'T'HH:mm:ss.SSS'Z',millis" 
) 
LOCATION 's3://bucket.me.com/raw/all-sites/'; 

ALTER TABLE site_sensor_data_raw ADD PARTITION (year='2017',month='03',day='09',hour='15') location 's3://bucket.me.com/raw/all-sites/2017/03/09/15'; 
ALTER TABLE site_sensor_data_raw ADD PARTITION (year='2017',month='03',day='09',hour='16') location 's3://bucket.me.com/raw/all-sites/2017/03/09/16'; 
ALTER TABLE site_sensor_data_raw ADD PARTITION (year='2017',month='03',day='09',hour='17') location 's3://bucket.me.com/raw/all-sites/2017/03/09/17'; 

DROP TABLE to_orc; 
CREATE EXTERNAL TABLE to_orc (
     count int, 
     dateTime8601 timestamp 
) 
STORED AS ORC 
LOCATION 's3://bucket.me.com/orc' 
TBLPROPERTIES ("orc.compress"="ZLIB"); 

INSERT OVERWRITE TABLE to_orc SELECT count,dateTime8601 FROM site_sensor_data_raw where year=2017 AND month=03 AND day=09 AND hour=15; 

回答

2

好了,默認JSON SERDE的使用在EMR和雅典娜不能在多行json記錄上工作。每個JSON記錄應該在一行中。

在多線JSON,我看到蜂巢/ Hadoop的兩個問題,甚至普雷斯托的(在Athean使用)的角度

  • 給定一個文件,其明顯的蜂巢/ Hadoop和JSON的SERDE的將不能識別json記錄的結束和開始以返回其對象表示。
  • 鑑於多個文件,多行JSON文件不像正常/ n分隔的JSON文件那樣可拆分。

爲了解決從EMR /雅典娜結束這個問題,你需要編寫自己的定製SERDE的基於數據結構和捕獲異常等

你如何設置流水忽略多行JSON?

Firehose無法忽略特定的格式。它將採用任何正在使用其API(PutRecord或PutRecordBatch)作爲數據blob並將它發送到目的地。

http://docs.aws.amazon.com/firehose/latest/APIReference/API_PutRecordBatch.html

不管怎樣,AWS流水提供數據轉換與AWS LAMBDA在那裏你可以使用lambda函數來轉換數據上的流水輸入數據,並把轉換後的數據到目的地。所以,你可能會使用該功能來識別並壓扁多線JSON。如果格式不正確,你也可能會丟失記錄。你將需要探索IOT如何發送多行json數據來排出(比如逐行等)來編寫你自己的函數。

https://aws.amazon.com/blogs/compute/amazon-kinesis-firehose-data-transformation-with-aws-lambda/

如果不可能,怎麼你告訴蜂房之前 裝載除去新行到表或至少捕獲異常,並試圖繼續?

如果您的firehose目標中仍然有多行JSON,由於您在ETL中有EMR,因此可以使用其計算而不是Lambda來平展JSON。火花上的這個功能也可以幫助你。 https://issues.apache.org/jira/browse/SPARK-18352

然後,您可以獲取這些數據,創建爲雅典娜工作的柱狀格式。