1. 首页 > 百货 > 家电数码

推出高性能 日志查询模式 更快更强 SLS SPL

随着数字化进程的持续深化,可观测性一直是近年来非常火热的话题,在可观测的三大支柱 Log/Trace/Metric中,日志(Log)数据一般是最为常见的,企业迈向可观测性的第一步,也往往始于日志数据的采集上云。日志完成收集后,最直接的需求就是从海量日志数据中检索分析出有价值的信息。随着日志数据量的不断增长,数据种类不断增多并日益朝着非结构化、多场景、多模态等方向演进,传统的日志搜索方式已经越来越难以满足不同场景下多样化、个性化的分析需求。

日志数据的查询分析需求是多样化的

日志(Log)数据作为可观测场景中最基础的数据类型之一,具备以下特点 :

这些因素导致日志数据在采集过程中往往并不存在一个理想的数据模型可以用来预处理日志数据,因此更常见的做法是直接采集存储原始的日志数据,这可以称为是一种 Schema-on-Read 的模式,或者是所谓的寿司原则(The Sushi Principle:Raw>

弱,主要就是支持关键词匹配

强,具备丰富的处理函数和算子,如正则匹配、json提取

输出内容是非结构化的

强,输出的是原文,便于查看

弱,输出的是表格模式,不存在的字段全部要补空值,不利于查看

简单,控制台可以直接点,API传递offset+lines即可

较复杂,需要在SQL中通过limit x,y的方式,并且要指定排序方式

简单,histogram柱状图直观展示出不同时间的分布

较复杂,需要在SQL中按照时间分组求和,再按时间排序,然后再画线图查看

结果中输出所有原文字段

输出的是原文,天然包含所有字段

较麻烦,select * 只能输出建了字段索引的列

可以通过with语句、SQL嵌套,但写起来较为复杂

既然两种方式各有所长,那么我们是否可以结合这两种方式的优点,支持一种新的查询语法,既能遵从文档模型(直接输出日志原文、不按表格模式、不要求所有输出列有索引),又能支持各种好用的 SQL 算子,同时还能够支持一种更便捷的级联处理(而不需要复杂的多层嵌套)呢?

SPL(详见SPL 概览[1]),即 SLS Processing Language,是 SLS 对日志查询、流式消费、数据加工、Logtail 采集、以及数据 Ingestion 等需要数据处理的场景,提供的统一的数据处理语法。

其中 <data-source> 是数据源,对于日志查询的场景,指的就是索引查询语句。<spl-expr> 是 SPL 指令,支持正则取值、字段分裂、字段投影、数值计算等多种丰富的操作,具体参考 SPL 指令介绍。

从语法定义上可以看到,SPL 是支持多个 SPL 指令组成管道级联的。对于日志查询的场景来说,在索引查询语句之后,可以根据需要通过管道符不断追加 SPL 指令,从而获得类似 Unix 管道处理文本数据的体验,对日志进行灵活的探索式分析。

筛选字段获得更精确的视图

在查询日志的时候,往往是带着某个目的去检索,这个时候一般是只关心其中的部分字段。这时就可以使用 SPL 中的 project 指令,只保留自己关心的字段。(或者使用 project-away 指令,移除不需要看到的字段)

使用 Extend 指令,可以基于已有字段加工提取出新的字段,可以使用丰富的函数(这些大部分是和 SQL 语法通用的)进行标量处理。

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 > 86

自由的展开半结构化数据

SPL 提供了 parse-json、parse-csv 这样的指令,可以将 json、csv 类型的字段,直接完全展开出为独立的字段,之后就可以直接对这些字段进行操作。省去了书写字段提取函数的开销,在交互式查询场景中这种写法是更为便捷的。

SPL 之前已经在扫描查询模式上全地域支持,详见扫描查询。扫描查询可以不依赖索引,直接扫描原始日志数据计算。下图中这个例子,就是在原始日志数据上,通过 SPL 管道完成了模糊过滤、json 展开、字段提取等多种操作。

当前扫描模式 SPL 难以处理大规模数据

扫描模式具备很好的灵活性,但最大的问题是性能不足,特别是面对大规模数据时难以在有限时间内处理完。现有的扫描查询限制单次最多扫描 10 万行,超出限制后需要控制台手动点击触发下一次扫描(或者 SDK 触发下一次调用)。

由于性能受限,导致现有的 SPL 查询在使用上存在以下问题:

这些约束,导致扫描模式下的 SPL,面对具备较大规模的日志数据,使用体验较差,也就很难发挥出实际用处。

为了从根本上改善 SPL 查询的执行性能,真正发挥出 SPL 灵活计算的优势。我们从计算架构、执行引擎、IO 效率等多个方面对 SPL 查询进行了重大优化。

首先要在架构上解决水平扩展的问题。原有的架构下,因为存储节点不具备复杂表达式的计算能力,只能将原始数据全量拉取到计算节点处理,大数据量的读取、传输、序列化是很大的瓶颈。

在查询场景下,实际单次请求每次需要的最终结果行数是比较少的(一般单次请求 100 行以内,超出后通过翻页请求获取),关键在于当 SPL 语句中包含 where 条件的时候,就存在从大量数据中计算 where条件过滤的过程。为了能够处理大规模数据并减少传输开销,我们就需要将 where 条件的计算下推到各个 shard所在的存储节点上处理。相应的,也就必须要求存储节点具备对 SPL 中丰富算子的高效处理能力。

为此我们在存储节点上,引入 C++ 向量化计算引擎,在存储节点上读取了原始的数据后,直接原地就可以进行高效的过滤计算。只有对满足 where 条件的日志,才需要进行剩余的 SPL 计算并输出最终结果。

计算下推之后,整个的处理能力就可以随着 shard 数目水平扩展,同时也大幅减少了存储节点和计算节点之间的数据传输、网络序列化开销。

向量化计算,多级火箭加速

计算下推解决了按 shard 水平扩展的问题,接下来我们还要进一步的大幅提升每个 shard 上的处理能力。

扫描模式的 SPL,最大性能瓶颈还是在于直接扫描读取原始的行数据。这样读放大会比较严重,IO 效率很低。正如使用 SQL分析能力时需要开启字段索引(并开启统计),这些字段的数据就可以被高效的读取和计算,那 SPL 同样也可以基于字段索引来进行高性能的数据IO,然后再基于 SIMD 向量化技术进行高性能计算,同时在过程中尽可能减少额外计算量。

以图中的 SPL 为例,在下推到存储节点后,会经过“多级火箭”进行层层加速:

经过这些优化之后,高性能 SPL 的执行性能相比扫描模式,得到了质的飞跃。

我们以单个 shard 处理 1 亿行数据为例,来评估高性能 SPL 的性能表现。在线上真实环境创建一个 Logstore,10 个 shard,查询时间范围内有 10 亿数据。(服务访问日志数据)

选取如下几个典型的场景:

场景 1:通过字符串函数处理后过滤

场景 2:短语查询、模糊查询

场景 3:json提取子字段,然后再过滤

在上述语句中选择不同的比较参数,构造出不同的命中率的场景(比如命中率 1%,指的是原始 10 亿条数据中,有 1000 万条满足 where 条件的结果数据),并请求前 20 条满足条件数据(对应 GetLogs 接口的 API 参数是 offset=0, lines=20),测试平均耗时。

控制台交互升级,展示过滤后结果的直方图

高性能模式 SPL,由于计算性能有了大幅提升,因此控制台展示 histogram,直接展示的是整个 SPL 语句过滤后的结果分布。(意味着整个范围内的数据也进行了全量的计算)

相应的,和纯索引查询模式下的交互完全相同,高性能模式 SPL 支持随机翻页,也支持点击柱状图直接跳转到对应区间的查询结果。

在高性能 SPL 模式下,调用 GetLogs 通过 SPL 语句查询日志时,offset 直接表示的就是过滤后的结果偏移量,从而大大简化了 API 调用方式。也就是说,使用上,和纯索引查询完全统一。直接按照过滤后最终结果的 offset 来翻页即可。

无须显式指定运行模式。当 SPL 语句中所有参与 where 条件计算的列,全都已经创建了字段索引(并开启了统计),则自动按照高性能模式执行;否则以扫描模式执行。

高性能 SPL 模式,查询本身不产生任何额外费用。

如果没有完全命中索引列导致走的是扫描模式 SPL(并且当前 Logstore 是按功能计费模式),则按照查询过程中的扫描原始日志数据量计费。

尽可能增加索引查询语句预过滤

如果有关键词索引过滤条件,尽可能使用,放在多级 SPL 管道的第一级。索引查询的效率总是最高的。

复杂过滤场景,建议使用 SPL 代替 SQL

特别是对于模糊匹配、短语匹配、正则匹配、json 提取以及更复杂的各种纯过滤场景,以前只能使用 SQL 语法(* | select * where XXX),现在建议替换为 SPL 语法(* | where XXX)。可以能更好的输出日志原文(而不是表格模式),更便捷的看到过滤后的结果柱状图分布,以及更简洁的输入体验。

目前 SPL 仅支持纯查询过滤场景下的使用,接下来在日志查询场景下,SPL 语法会进一步支持排序、聚合等操作(聚合后按照表格模式输出),从而使得 SPL 的多级管道级联处理能力更强大、更完善,能够更好的对日志进行更灵活的查询分析。

企业的日志数据上云后,从海量日志中搜索出想要的信息,是一项最基本的需求。SLS 推出 SPL 查询语法,支持类似 Unix 管道的级联语法,并支持 SQL的各种丰富的函数。同时,基于计算下推、向量化计算等优化,支持高性能模式 SPL 查询,可以在数秒内处理亿级数据,并且支持 SPL过滤后最终结果的分布直方图、随机翻页等特性,具备和纯索引查询模式类似的体验。对于模糊、短语、正则、json 提取以及各种复杂过滤场景,推荐使用SPL 语句来进行查询。

高性能模式 SPL 目前正在按区域逐步发布中,有任何使用上的问题或者需求,可以通过工单或者直接在 SLS 的钉钉群咨询。SLS 会一直持续不断的优化,提供更强大、更好用的可观测存储分析引擎。

本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载者并注明出处:https://www.jmbhsh.com/jiadianshuma/36392.html

联系我们

QQ号:***

微信号:***

工作日:9:30-18:30,节假日休息