使用 Hive 脚本处理每个 start/end 对的时间跨度
Process timespan for each start/end pair using Hive script
我有一个可以启动或停止的服务。每个操作都会生成一条带有时间戳和操作类型的记录。最终,我得到了一系列带有时间戳的操作记录。现在我想计算一天中服务的正常运行时间。这个想法很简单。对于每对 start/stop 记录,计算时间跨度并求和。但我不知道如何用 Hive 实现它,如果可能的话。我为此创建表来存储中间结果是可以的。这是主要的阻塞问题,还有一些其他的小问题。例如,一些 start/stop 对可能跨越一天。任何想法如何处理这个小问题也将不胜感激。
示例数据:
Timestamp Operation
... ...
2017-09-03 23:59:00 Start
2017-09-04 00:01:00 Stop
2017-09-04 06:50:00 Start
2017-09-04 07:00:00 Stop
2017-09-05 08:00:00 Start
... ...
2017-09-04
的服务正常运行时间应为 1 + 10 = 11
分钟。请注意,第一个时间间隔跨越 09-03
和 09-04
,并且只计算落在 09-04
内的部分。
select to_date(from_ts) as dt
,sum (to_unix_timestamp(to_ts) - to_unix_timestamp(from_ts)) / 60 as up_time_minutes
from (select case when pe.i = 0 then from_ts else cast(date_add(to_date(from_ts),i) as timestamp) end as from_ts
,case when pe.i = datediff(to_ts,from_ts) then to_ts else cast(date_add(to_date(from_ts),i+1) as timestamp) end as to_ts
from (select `operation`
,`Timestamp` as from_ts
,lead(`Timestamp`) over (order by `Timestamp`) as to_ts
from t
) t
lateral view posexplode(split(space(datediff(to_ts,from_ts)),' ')) pe as i,x
where `operation` = 'Start'
and to_ts is not null
) t
group by to_date(from_ts)
;
+------------+-----------------+
| dt | up_time_minutes |
+------------+-----------------+
| 2017-09-03 | 1.0 |
| 2017-09-04 | 11.0 |
+------------+-----------------+
我有一个可以启动或停止的服务。每个操作都会生成一条带有时间戳和操作类型的记录。最终,我得到了一系列带有时间戳的操作记录。现在我想计算一天中服务的正常运行时间。这个想法很简单。对于每对 start/stop 记录,计算时间跨度并求和。但我不知道如何用 Hive 实现它,如果可能的话。我为此创建表来存储中间结果是可以的。这是主要的阻塞问题,还有一些其他的小问题。例如,一些 start/stop 对可能跨越一天。任何想法如何处理这个小问题也将不胜感激。
示例数据:
Timestamp Operation
... ...
2017-09-03 23:59:00 Start
2017-09-04 00:01:00 Stop
2017-09-04 06:50:00 Start
2017-09-04 07:00:00 Stop
2017-09-05 08:00:00 Start
... ...
2017-09-04
的服务正常运行时间应为 1 + 10 = 11
分钟。请注意,第一个时间间隔跨越 09-03
和 09-04
,并且只计算落在 09-04
内的部分。
select to_date(from_ts) as dt
,sum (to_unix_timestamp(to_ts) - to_unix_timestamp(from_ts)) / 60 as up_time_minutes
from (select case when pe.i = 0 then from_ts else cast(date_add(to_date(from_ts),i) as timestamp) end as from_ts
,case when pe.i = datediff(to_ts,from_ts) then to_ts else cast(date_add(to_date(from_ts),i+1) as timestamp) end as to_ts
from (select `operation`
,`Timestamp` as from_ts
,lead(`Timestamp`) over (order by `Timestamp`) as to_ts
from t
) t
lateral view posexplode(split(space(datediff(to_ts,from_ts)),' ')) pe as i,x
where `operation` = 'Start'
and to_ts is not null
) t
group by to_date(from_ts)
;
+------------+-----------------+
| dt | up_time_minutes |
+------------+-----------------+
| 2017-09-03 | 1.0 |
| 2017-09-04 | 11.0 |
+------------+-----------------+