本文主要是介绍Hive_SQL_复杂SQL_计算最大在线人数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
原文链接:
1.Hive SQL复杂场景实现(2) —— 实时/最大在线人数
Hive SQL复杂场景实现(2) —— 实时/最大在线人数_复杂的hive sql实现思路_XinyuWg的博客-CSDN博客
背景
之前遇到这个问题:,能不能用SQL求某一天哪个时刻进行中的订单量最多,这个数是多少?我寻思挺有意思,就细想了一下。其实思考下可以发现,如果要求一段时间内的同时处于服务过程中的最大订单量,相当于也要知道每个时刻的数量,所以求最大和求实时是等同的。
这个问题在不同的业务场景下有不同的意义,比如一个游戏的同时在线人数,比如一个服务器的实时并发数,比如一个仓库的货物积压数量等等。
一般而言对于需要知道并发数的业务场景都会通过实时监控来完成,而不会通过sql进行离线计算。但本着深挖sql潜能的想法,如下提供一个不切实际的解法与一个真实可行的方法。
数据
假设我们的业务场景是回溯某一天的某游戏的最大同时在线人数,并有表connection_detail记录用户每一次上线和下线时间:
user_id | login_time | logout_time | dt |
213142 | 2019-01-01 12:21:22 | 2019-01-01 13:45:21 | 20190101 |
412321 | 2019-01-01 13:35:11 | 2019-01-01 16:01:49 | 20190101 |
… | … | … | … |
解法
大致思路 窗口函数 sum() over()
我们先抛开sql,来考虑实时计算中我们怎么处理该问题。是不是我们会实时记录着一个变量online_cnt,当一个用户登录时加1,用户下线时减1?
再假如我让你用python离线处理这个问题你会怎么做。应该先把登录时间和登出时间这两列打散成行,然后进行排序,最后一行行读入,当读到一个登录时间时online_cnt加1,读到登出时间时online_cnt减1。
回到sql,我们来尝试用SQL实现上述逻辑。我们给登录时间加一个数值标记1,登出时间加标记-1。然后对排序后的数据求和该字段,最终得到我们的结果。
select
max(max_index)
from
(
select
sum(index) over(order by `timestamp`) as max_index --排序后第一行到本行的和
from
(
select
order_id,
unix_timestamp(login_time) as `timestamp`,
1 as index
from
connection_detail
where
dt = '20190101'
and is_td_finish = 1
union all
select
order_id,
unix_timestamp(logout_time) as `timestamp`,
-1 as index
from
connection_detail
where
dt = '20190101'
)a --将登录时间和登出时间多列成多行
)b
可能阻碍大家想到这一逻辑的点在于sum() over()这一用法,该窗口函数对每一行数据实现了计算第一行到该行的求和计算,具体介绍网上很多,不熟悉的同学可以百度一下。该代码对于千万量级的数据sparksql计算了65秒,属于一个可以接受的范围。
理解了上述代码的同学可以发现过程中我们一度得到了每个时刻的在线人数(子查询b)。对这一数据进行可视化可以直观了解服务器的负载变化情况。
这篇关于Hive_SQL_复杂SQL_计算最大在线人数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!