Amazon web services AWS Athena创建表和分区
我将传感器数据存储在S3中(每5分钟写入一次数据): 1541252701443是一个json文件,其中包含测量值:Amazon web services AWS Athena创建表和分区,amazon-web-services,amazon-s3,hive,amazon-athena,Amazon Web Services,Amazon S3,Hive,Amazon Athena,我将传感器数据存储在S3中(每5分钟写入一次数据): 1541252701443是一个json文件,其中包含测量值: { "temperature": 14.78, "pressure": 961.70, "humidity": 68.32} 我肯定缺少一些蜂巢技能。不幸的是,我没有找到一个能够提取timeseries json数据的示例。我也不确定蜂巢/雅典娜是否支持这种数据争夺 我正在努力为这些数据创建一个雅典娜表 CREATE EXTERNAL TABLE IF NOT EXIST
{ "temperature": 14.78, "pressure": 961.70, "humidity": 68.32}
我肯定缺少一些蜂巢技能。不幸的是,我没有找到一个能够提取timeseries json数据的示例。我也不确定蜂巢/雅典娜是否支持这种数据争夺
我正在努力为这些数据创建一个雅典娜表
CREATE EXTERNAL TABLE IF NOT EXISTS farm.sensor_data (
device string,
sensor string,
data_point string,
value double
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1'
) LOCATION 's3://farm-iot/sensor_data/farm/farm0001/sensor01/'
PARTITIONED BY (timestamp string)
TBLPROPERTIES ('has_encrypted_data'='false')
我想的另一种方法是将数据存储在一个更容易处理的结构中/也许我没有对数据进行足够的分区
因此,也许我应该向结构中添加dt,如下所示:
farm_iot/sensor_data/2018-11-03-02-45-02/farm/farm0001/sensor01/1541252701443
仍然无法让我达到我想要的目标:
+---------------+----------+----------+-------------+--------+
| timestamp | device | sensor | data_point | value |
+---------------+----------+----------+-------------+--------+
| 1541252701443 | farm0001 | sensor01 | temperature | 14.78 |
+---------------+----------+----------+-------------+--------+
| 1541252701443 | farm0001 | sensor01 | humidity | 68.32 |
+---------------+----------+----------+-------------+--------+
| 1541252701443 | farm0001 | sensor01 | pressure | 961.70 |
+---------------+----------+----------+-------------+--------+
任何指向这一目标的指针都将不胜感激。谢谢大家!
请注意:我不想使用胶水,我想了解如何手动操作。此外,glue昨天已经创建了约16000个表:)让我试着解释一下我在前面看到的一些问题
- 看起来您所需的输出需要一些数据,这些数据是路径文件位置、设备和传感器的一部分,但是它没有定义为表定义的一部分,只有表定义中的列或将可用李>
- 几个小文件可能会影响查询的性能(但这不会影响所需的结果)
- 配置单元分区用于提高查询的性能,避免扫描 所有的数据。分区指向文件夹,在这种情况下,您试图访问特定的文件
- 您想要的输出基本上是将一条记录分解成多条记录,这不应该在表定义中处理,可以通过select语句来完成
- 配置单元分区的命名约定为
,这不是强制性的,但如果您希望提前使用命令根据文件夹结构自动添加分区,则此约定非常有用李>partitionname=partitionvalue
farm_iot/sensor_data/farm/farm0001/sensor01/1541252701443
至农场物联网/传感器数据/农场/设备=农场0001/传感器=传感器01/1541252701443
更改表定义
您的表定义应该包含您的分区位置,以便能够在不使用正则表达式的情况下选择它,并利用它的性能改进(我猜一个常见查询将按设备或传感器进行过滤。此外,您还需要添加文件中的所有json列)
CREATE EXTERNAL TABLE IF NOT EXISTS farm.sensor_data (
temperature double,
preassure double,
humidity double
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1'
) LOCATION 's3://farm-iot/sensor_data/farm/'
PARTITIONED BY (device string, sensor string)
TBLPROPERTIES ('has_encrypted_data'='false')
查询您的数据
我们缺少时间戳,它本质上是json输入文件名的一部分。我们可以在select语句中使用虚拟列input\u file\u name
包含文件名,如下所示
select device, sensor, temperature, preassure, humidity, INPUT__FILE__NAME as mytimestamp from farm.sensor_data
ALTER TABLE test ADD PARTITION (device='farm0001', sensor='sensor01') location 's3://farm_iot/sensor_data/farm/farm0001/sensor01'
如果您需要预压力、温度和湿度以及不同的行,我建议您使用这三个行创建一个数组并将其分解,使用UNION ALL运行3个查询以附加结果应该会非常有效
添加新分区
如果遵循配置单元约定,则可以利用该命令在包含新设备/传感器后自动添加新分区。在最坏的情况下,如果要保留文件夹结构,可以按如下方式添加分区
select device, sensor, temperature, preassure, humidity, INPUT__FILE__NAME as mytimestamp from farm.sensor_data
ALTER TABLE test ADD PARTITION (device='farm0001', sensor='sensor01') location 's3://farm_iot/sensor_data/farm/farm0001/sensor01'
注意:新分区不会自动添加,您始终需要添加它们
我试着尽可能多地添加细节。如果有什么不清楚,请告诉我
编辑:
如果您的查询主要基于时间序列(例如日期范围),我建议在日级别添加一个分区(不小于此分区),以提高查询的性能
CREATE EXTERNAL TABLE IF NOT EXISTS farm.sensor_data (
temperature double,
preassure double,
humidity double
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1'
) LOCATION 's3://farm-iot/sensor_data/farm/'
PARTITIONED BY (dt=long, device string, sensor string)
TBLPROPERTIES ('has_encrypted_data'='false')
您的文件夹结构如下所示
CREATE EXTERNAL TABLE IF NOT EXISTS farm.sensor_data (
temperature double,
preassure double,
humidity double
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1'
) LOCATION 's3://farm-iot/sensor_data/farm/'
PARTITIONED BY (dt=long, device string, sensor string)
TBLPROPERTIES ('has_encrypted_data'='false')
农场物联网/传感器数据/农场/dt=20191204/设备=farm0001/传感器=sensor01/1541252701443
作为说明,您不需要为每个新分区修改表,只需将此分区添加到表中,这基本上就是Hive知道新分区已创建的方式。如果您决定使用分区,这是唯一的方法,如果您不使用(这将影响性能),还有其他一些方法可以让它发挥作用
编辑2:
如果您希望保持数据结构不变,并且不使用分区,那么可以得到如下预期结果
CREATE EXTERNAL TABLE IF NOT EXISTS yourdb.sensordata (
temperature double,
pressure double,
humidity double
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1'
)
LOCATION 's3://farm-iot/sensor_data/farm/'
TBLPROPERTIES ('has_encrypted_data'='false');
SET hive.mapred.supports.subdirectories=TRUE;
SET mapred.input.dir.recursive=TRUE;
select * from yourdb.sensordata;
select
split(input__file__name, "/")[size(split(input__file__name, "/")) - 1] as ts,
split(input__file__name, "/")[size(split(input__file__name, "/")) - 3] as device,
split(input__file__name, "/")[size(split(input__file__name, "/")) - 2] as sensor,
'temperature' as data_point,
temperature as value
from yourdb.sensordata
union all
select
split(input__file__name, "/")[size(split(input__file__name, "/")) - 1] as ts,
split(input__file__name, "/")[size(split(input__file__name, "/")) - 3] as device,
split(input__file__name, "/")[size(split(input__file__name, "/")) - 2] as sensor,
'pressure' as data_point,
pressure as value
from yourdb.sensordata
union all
select
split(input__file__name, "/")[size(split(input__file__name, "/")) - 1] as ts,
split(input__file__name, "/")[size(split(input__file__name, "/")) - 3] as device,
split(input__file__name, "/")[size(split(input__file__name, "/")) - 2] as sensor,
'humidity' as data_point,
humidity as value
from yourdb.sensordata;
如您所见,我从文件路径获取了大部分信息,但是需要设置一些标志以递归方式告知配置单元读取文件夹
ts,device,sensor,_data_point,value
1541252701443,farm0001,sensor01,temperature,14.78
1541252701443,farm0001,sensor01,pressure,961.7
1541252701443,farm0001,sensor01,humidity,68.32
首先,非常感谢@hlagos的帮助 AWS Athena无法以我需要的方式转换json传感器数据(我们在@hlagos答案的评论中对此进行了讨论)。因此,处理这种情况的“最简单”方法是将数据格式从json更改为CSV,以更接近我需要的格式 现在,我将传感器数据以CSV格式存储在S3中(每5分钟写入一次数据),并添加了我们讨论的日期和设备分区 生成的文件夹结构:
farm_iot/sensor_data/farm/day=20181129/device=farm0001/1543535738493
CSV文件的数据内容:
sensor01,temperature,2.82
sensor01,pressure,952.83
sensor01,humidity,83.64
sensor02,temperature,2.61
sensor02,pressure,952.74
sensor02,humidity,82.41
AWS雅典娜表格定义:
CREATE EXTERNAL TABLE IF NOT EXISTS farm.sensor_data (
`sensor` string,
`data_point` string,
`value` double
)
PARTITIONED BY (day string, device string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
ESCAPED BY '\\'
LINES TERMINATED BY '\n'
LOCATION 's3://farm-iot/sensor_data/farm/'
TBLPROPERTIES ('has_encrypted_data'='false');
我添加的分区如下(稍后我将有一个脚本来提前创建分区):
现在我可以查询数据了:
select regexp_extract("$path", '[^/]+$') as timestamp, device, sensor,
data_point, value from farm.sensor_data where day='20181104'
Results
timestamp device sensor data_point value
1 1541310040278 farm0001 sensor01 temperature 21.61
2 1541310040278 farm0001 sensor01 pressure 643.65
3 1541310040278 farm0001 sensor01 humidity 74.84
4 1541310040278 farm0001 sensor02 temperature 9.14
5 1541310040278 farm0001 sensor02 pressure 956.04
6 1541310040278 farm0001 sensor02 humidity 88.01
7 1541311840309 farm0001 sensor01 temperature 21.61
8 ...
写入数据或创建表时是否遇到错误?请发布错误消息。@VamsiPrabhala抱歉,这不是“我有一个错误问题”刚用另一种方法编辑,以保持数据的当前格式,但是性能不如使用分区。只需添加一篇文章,详细说明我正在使用的内容,谢谢你的回答。我不太喜欢你建议的表格更改,因为我必须更改每种新传感器类型的表格定义我介绍一下。如果我理解正确,那么就不可能将json数据配置为我想要的格式。这意味着我最好将传感器数据存储为csv格式(“设备”、“传感器”、“数据”)