引言
Cloud Native
日志数据的查询分析需求是多样化的
日志(Log)数据作为可观测场景中最基础的数据类型之一,具备以下特点 :
不可变:日志数据一旦产生就不会被再次修改,是对事件原始信息的忠实记录,往往结构不太固定。
数据随机:比如异常事件日志、用户行为日志,一般天然就是随机的、难以预测的。
来源多样:日志数据种类繁多,不同来源的数据难以具有统一的 Schema。
业务复杂:不同的业务参与方对数据的理解不同,写日志过程中难以预见到后期具体的分析需求。
理想的日志查询语法应该是什么样的
日志数据分析通常可以分为两大类场景:
SPL 管道式查询语言
Cloud Native
SPL(详见 SPL 概览[1]),即 SLS Processing Language,是 SLS 对日志查询、流式消费、数据加工、Logtail 采集、以及数据 Ingestion 等需要数据处理的场景,提供的统一的数据处理语法。
<data-source> | <spl-expr> ... | <spl-expr> ...SPL 能做什么?
实时计算出新的字段
Status:200 | extend urlParam=split_part(Uri, '/', 3)同时也可以根据多个字段计算出新的字段,比如计算两个数字字段的差值。(注意字段默认是被视为 varchar,进行数字类型计算的时候要先通过 cast 转换类型)
Status:200 | extend timeRange = cast(BeginTime as bigint) - cast(EndTime as bigint)并且也可以在后续管道中,再对这个计算后的值进行 where 判断过滤:
Status:200| where UserAgent like '%Chrome%'| extend timeRange = cast(BeginTime as bigint) - cast(EndTime as bigint)| where timeRange > 86400
自由的展开半结构化数据
当前扫描模式 SPL 难以处理大规模数据
扫描模式具备很好的灵活性,但最大的问题是性能不足,特别是面对大规模数据时难以在有限时间内处理完。现有的扫描查询限制单次最多扫描 10 万行,超出限制后需要控制台手动点击触发下一次扫描(或者 SDK 触发下一次调用)。
对于过滤结果较为稀疏的查询,由于单次扫描的原始数据量太少,很难在有限时间内扫描到结果。
查询界面的直方图展示的是索引过滤后的结果(以及扫描进度),而无法展示出 SPL 条件过滤后的最终结果分布。
无法支持针对最终过滤后的结果随机翻页,只能按照已经扫描的原文的 offset 进行连续翻页扫描。
这些约束,导致扫描模式下的 SPL,面对具备较大规模的日志数据,使用体验较差,也就很难发挥出实际用处。
极致优化,高性能 SPL 模式
Cloud Native
为了从根本上改善 SPL 查询的执行性能,真正发挥出 SPL 灵活计算的优势。我们从计算架构、执行引擎、IO 效率等多个方面对 SPL 查询进行了重大优化。
计算下推,并行化加速
首先要在架构上解决水平扩展的问题。原有的架构下,因为存储节点不具备复杂表达式的计算能力,只能将原始数据全量拉取到计算节点处理,大数据量的读取、传输、序列化是很大的瓶颈。
向量化计算,多级火箭加速
计算下推解决了按 shard 水平扩展的问题,接下来我们还要进一步的大幅提升每个 shard 上的处理能力。
按照查询时间范围过滤(当数据量非常大时,建议选择必要的时间范围进行分析)。
处理第一级管道 Status:200 ,关键词索引条件过滤(这个是最快的,有索引过滤条件尽量写上过滤条件)。
处理 SPL 中的 where 过滤条件,基于字段索引(并开启统计),高效读取对应的数据。
向量化高性能计算,获得过滤结果,然后再计算剩余的 SPL 部分,得到最终结果
同时在计算过程中,如果发现过滤结果行数已经满足要求,则尽量提前终止(特别对于高命中率的情形,可以尽量减少不必要的计算)。
高性能 SPL 的性能表现
我们以单个 shard 处理 1 亿行数据为例,来评估高性能 SPL 的性能表现。在线上真实环境创建一个 Logstore,10 个 shard,查询时间范围内有 10 亿数据。(服务访问日志数据)
场景 1:通过字符串函数处理后过滤
场景 2:短语查询、模糊查询
场景 3:json提取子字段,然后再过滤
可以看出:
当命中率较高时,不同场景下都有很好的性能表现,甚至可以接近关键词索引查询。
当命中率很低时,由于要实时计算大量数据,需要更长一些的执行时间,具体实际性能表现和数据字段的长度、语句中算子复杂度、命中结果在原始数据的分布位置等因素都有关。
整体来看,高性能 SPL 对于数十亿级别的日志量级,可以在数秒内完成计算。
控制台交互升级,展示过滤后结果的直方图
高性能模式 SPL,由于计算性能有了大幅提升,因此控制台展示 histogram,直接展示的是整个 SPL 语句过滤后的结果分布。(意味着整个范围内的数据也进行了全量的计算)
举个例子,原始日志有 1000 万条,SPL 语句是 Status:200 | where Category like '%xx%',符合 Status:200 条件的日志是 10 万条,这其中再符合 where Category like '%xx%' 条件的日志是 1000 条,则查询界面上 histogram 柱状图展示的是这最终的 1000 条日志随时间的分布情况。
相应的,和纯索引查询模式下的交互完全相同,高性能模式 SPL 支持随机翻页,也支持点击柱状图直接跳转到对应区间的查询结果。
API 调用简化,统一的 offset 语义
使用说明
Cloud Native
如何开启高性能 SPL?
无须显式指定运行模式。当 SPL 语句中所有参与 where 条件计算的列,全都已经创建了字段索引(并开启了统计),则自动按照高性能模式执行;否则以扫描模式执行。
是否计费?
高性能 SPL 模式,查询本身不产生任何额外费用。
最佳实践
尽可能增加索引查询语句预过滤
复杂过滤场景,建议使用 SPL 代替 SQL
特别是对于模糊匹配、短语匹配、正则匹配、json 提取以及更复杂的各种纯过滤场景,以前只能使用 SQL 语法(* | select * where XXX),现在建议替换为 SPL 语法(* | where XXX)。可以能更好的输出日志原文(而不是表格模式),更便捷的看到过滤后的结果柱状图分布,以及更简洁的输入体验。
更多功能,敬请期待
Cloud Native
SPL 也能支持聚合操作
目前 SPL 仅支持纯查询过滤场景下的使用,接下来在日志查询场景下,SPL 语法会进一步支持排序、聚合等操作(聚合后按照表格模式输出),从而使得 SPL 的多级管道级联处理能力更强大、更完善,能够更好的对日志进行更灵活的查询分析。
总结
Cloud Native
企业的日志数据上云后,从海量日志中搜索出想要的信息,是一项最基本的需求。SLS 推出 SPL 查询语法,支持类似 Unix 管道的级联语法,并支持 SQL 的各种丰富的函数。同时,基于计算下推、向量化计算等优化,支持高性能模式 SPL 查询,可以在数秒内处理亿级数据,并且支持 SPL 过滤后最终结果的分布直方图、随机翻页等特性,具备和纯索引查询模式类似的体验。对于模糊、短语、正则、json 提取以及各种复杂过滤场景,推荐使用 SPL 语句来进行查询。
钉钉扫码加入日志服务 SLS 服务群
相关链接:
https://help.aliyun.com/zh/sls/user-guide/spl-overview
https://help.aliyun.com/zh/sls/user-guide/spl-instruction