基于窗口的实时统计

窗口统计

实时数据是无边界的,即不断地有数据输入,但我们的统计一般是有时间范围的,离线统计以年月日为统计周期,最小能到小时周期,如果是分钟甚至秒级别计算,则可认为是实时计算,我们把实时数据流按时间段分割成一个个窗口,则可基于窗口进行数据统计。

我司开源Pike支持三种窗口,结合各种UDAF,通过SQL就能能实现各种聚合统计:

  • 跳动窗口
  • 滑动窗口
  • 累计窗口

跳动窗口

跳动窗口是最直观,最简单的接口,如下图,t1->t2为一个窗口,t2->t3为一个窗口,各个窗口之间没有重叠,实时统计结果也是基于各个窗口内的数据,结果输出频率等于统计周期。

跳动窗口比较常用,一般适用于统计无交叉分钟级别实时流量。

pike example:

 //以5m为输出频率,统计客户端每5分钟各视频播放uv,并按uv排序,获取uv最高的top 100视频
 withperiod 5m 
 select  top 100 output(dt(outputctx())) as dt,
 output('pc客户端') as plt,
 mjoin(dim_channelid,'dim_sync_channel','Series_TitleChinese') as title,
 count(distinct userid, ipvalue) as UV
 from dol_client
 group by title
 order by uv desc

滑动窗口

滑动窗口相对跳动窗口稍复杂,主要在于相邻窗口间有重叠,如下图,t1->t3为窗口w1,t2->t4为窗口w2,w2与w1重叠t2->t3,此时w2相对w1滑动窗口为t1->t2,w1统计窗口为t1->t3, 统计窗口必须为滑动窗口的整数倍,即(t3-t1)%(t2-t1)=0。若统计窗口等于滑动窗口,则滑动窗口转化为跳动窗口,因此,可认为跳动窗口是滑动窗口的特例。

滑动窗口主要适用于统计最近m时间内数据,输出结果间隔为n, n <= m 且 m % n = 0。

pike example:

//以5分钟为输出频率,同时统计最近5分钟,最近10分钟,最近4小时网页端点直播uv和vv
withperiod 5m
select output(dt(outputctx())) as dt,
'ikan' as plt,
case when Dim_LiveOndemand_C=102 then '点播' else '直播' end as type,
count(distinct userid,ipvalue) as uv_5m,
count(distinct userid,ipvalue,channelid) as vv_5m,
move('10m',count(distinct userid,ipvalue)) as uv_10m,
move('10m',count(distinct userid,ipvalue,channelid)) as vv_10m,
move('4h',linearcount(10000000,userid,ipvalue)) as uv_4h,
move('4h',linearcountEx(100,userid,ipvalue,channelid)) as vv_4h,
from dol_ikan
group by plt,type

累计窗口

累计窗口则是累计一个时间段内数据不断输出,例如w1为从t1开始累计到t2的数据,w2为从t1开始累计到t3的数据,w3为从t1开始累计到t4的数据,w1、w2、w3共享初始状态;在一个完整的累计周期内,完整累计周期必须为输出频率的整数倍,t1为初始状态,t2输出w1统计结果,t3输出w2统计结果,t4输出w3统计结果,t2-t1=t3-t2=t4-t3,(t3-t1)%(t2-t1)=0,(t4-t1)%(t2-t1)=0;下一个完整累计周期则清零为初始化状态重新开始统计,例如w6,w3都是一个完整累计窗口,且w6,w3无交集,w6,w3之间如同跳动窗口。

累计窗口主要适用于获取从整点或整天开始,累计到当前时间的统计数据,一般完整累计窗口与离线周期对应,但却需要获取当前时刻的实时统计数据,例如实时获取当天累计vv、当前小时累计uv。

pike examlpe:

//以5分钟为输出频率,实时统计移动端各视频当前小时uv、vv以及当天累计uv、vv
withperiod 5m 
select  output(dt(outputctx())) as dt,
channelid,
count(1) as LogCount,
count(distinct userid, ipvalue) as UV,
count(distinct if(StrIsNullOrEmpty(vvid), userid + channelid, vvid)) as VV,
accumulate('1h', count(1)) as LogCount_ThisHour,
accumulate('1h', linearcount(10000000, userid, ipvalue)) as UV_ThisHour
accumulate('1h', linearcountEx(100, if(StrIsNullOrEmpty(vvid), userid + channelid, vvid))) as VV_ThisHour,
accumulate('1d', count(1)) as LogCount_ThisDay,
accumulate('1d', hyperloglogcount(5, userid, ipvalue)) as UV_ThisDay,
accumulate('1d', loglogadaptivecount(5, if(StrIsNullOrEmpty(vvid), userid + channelid, vvid))) as VV_ThisDay
from dol_smart
group by channelid
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值