我有一个 AWS IoT 规则,它将传入的 JSON 发送到 Kinesis Firehose。
来自我的 IoT 发布的 JSON 数据都集中在一行上 - 例如:
{"count":4950, "dateTime8601": "2017-03-09T17:15:28.314Z"}
管理 UI 中的 IoT“测试”部分允许您发布消息,默认为以下(注意格式化的多行 JSON):
{
"message": "Hello from AWS IoT console"
}
我将 Firehose 流式传输到 S3,然后由 EMR 转换为柱状格式,最终由 Athena 使用。
问题是,在转换为列格式期间,Hive(特别是JSON SerDe)无法处理跨越多行的 JSON 对象。它会破坏转换,而不是转换良好的单行 JSON 记录。
我的问题是:
- 如何设置 FireHose 以忽略多行 JSON?
- 如果不可能,如何告诉 Hive 在加载到表之前删除换行符,或者至少捕获异常并尝试继续?
在定义 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;