背景
阿里云专有网络(VPC)提供流日志功能,支持VPC网络中弹性网卡流量、VPC流量及交换机流量的记录与存储。对流日志分析可以监控访问控制规则、监控网络流量和排查网络故障。
流日志功能捕获的流量信息以日志方式写入SLS(阿里云日志服务)中。每条日志会捕获特定捕获窗口中的特定五元组网络流,捕获窗口大约为10分钟,该段时间内流日志功能先聚合数据,再发布日志。
在 SLS 上可以通过关键词搜索对指定目标地址被拒绝的请求:
也可以通过 SLS 的 SQL 进行统计分析,但这里涉及一个捕获窗口的问题,例如下面两条流日志(字段做了简化):
Log#1 start: 2021-05-31 00:00:00 end: 2021-05-31 00:08:30 bytes: 9000 packets: 18 Log#2 start: 2021-05-31 00:02:30 end: 2021-05-31 00:03:15 bytes: 5000 packets: 10
采集窗口内产生的 bytes,落到 start 时间点上去或是平均落到整个采集窗口,对于流量分析结果会产生明显的差异:
根据不同的业务背景,可以有不同的选择:
一种方法是按采集窗口开始时间计算,方法简单,select from_unixtime(start - start % 60) as dt, sum(bytes) as total_bytes group by dt order by dt asc limit 1000
。
另一种较为复杂,拆分采集窗口后计算,本文介绍基于 SLS SQL 拆分日志后重新聚合的分析实践。
方案
如下是一条 start 与 end 相差501的日志,表示采集窗口横跨了 502 个秒级时间段(start、end 是左闭右闭区间):
利用数据函数 sequence 可以生成一个时间序列到 ta 字段:
接着将 ta 序列做 unest 展开,得到 502 条日志:
到这里,基本思路就有了。但一定请注意:
- packets、bytes 字段是在一个捕获窗口中获得的,所以展开后的每条日志,应该将指标值均分到每个拆分后的时间段。
- 窗口数据展开后,意味着日志量会膨胀,可能产生很大的计算压力与存储成本,建议减少聚合指标分组数目。
为了减少日志条数,我们将拆分后的秒级日志再按照10秒级粒度重新聚合,502 条秒级日志变为 51 条十秒级日志:
Scheduled SQL 实践
将以上方案常驻执行,就可以实现对于新日志的增量处理,如果将预处理结果保存到 Logstore,我们就可以在新的 Logstore 上做分析,可以做到更低的延迟。
Scheduled SQL 是一项由 SLS 全托管的功能,主要的场景包括:
- 定时分析数据:根据业务需求设置 SQL 语句或查询分析语句,定时执行数据分析,并将分析结果存储到目标库中。
- 全局聚合:对全量、细粒度的数据进行聚合存储,汇总为存储大小、精度适合的数据,相当于一定程度的有损压缩数据。
执行如下 SQL 预览并确认结果符合预期(如果希望预处理后的数据量更少一些,可以按照分钟粒度做聚合,将 10 替换为 60),SQL 代码:
* | select (t.time - t.time % 10) as __time__, srcaddr, srcport, dstaddr, dstport, action, protocol, sum(bytes * 1.0 / ("end"-start + 1)) as bytes, sum(packets * 1.0 / ("end"-start + 1)) as packets from (select start, "end", srcaddr, srcport, dstaddr, dstport, action, protocol, bytes, packets, sequence(start, "end", 1) as ta from log), unnest(ta) as t(time) group by time, srcaddr, srcport, dstaddr, dstport, action, protocol order by __time__ asc limit 1000000
紧接着创建 Scheduled SQL 作业:
保存作业,选择”增强型资源池“(收费、但资源可扩展,适用于有 SLA 要求的业务场景),设置存储预处理结果到目标 Logstore aligned_vpc_flowlog。
接下来,设置 SQL 作业从 5/28 日的数据开始处理,在存量数据追上进度后,新数据每 5 分钟执行一次,每次查询 5 分钟的数据做处理。
注意延迟执行参数,如果上游 Logstore 的数据到来可能延迟,建议设置大一些的值来保证计算数据的完整性。
Scheduled SQL 作业每 5 分钟一次的实例,可以在控制台上查看到。对于 SQL 执行失败(权限、SQL 语法等原因)或者数据迟到导致空跑情况,可以对指定实例做重试运行。
效果
在 SLS 上制作一个仪表盘对比两种计算方式的流量特征。
- 10秒聚合-原始窗口
* | select from_unixtime(start - start % 10) as dt, sum(packets) as packets, round(sum(bytes)/1024.0/1024.0, 3) as MB group by dt order by dt asc limit 10000
- 10秒聚合-拆分窗口数据
* | select from_unixtime(__time__ - __time__ % 10) as dt, sum(packets) as packetes, round(sum(bytes)/1024.0/1024.0, 3) as MB group by dt order by dt asc limit 10000
通过对比可以看到,拆分窗口后的数据统计更加均匀。
更多其它内容,请参考: