数据加工DSL编译优化:搜索算子语义等价转换

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本次分享主要介绍面向数据加工DSL的一项编译优化:搜索算子语义等价转换。e_search()是灵活的语义丰富的搜索算子,通过简洁的DSL即可实现复杂的搜索需求。搜索过滤是日志处理的基本功能,在数据加工作业中搜索算子被极高频使用(数据加工共200+算子,搜索算子e_search()使用频度排名top 5)。搜索算子支持哪些语法?搜索算子语义等价转换是怎么实现的?有哪些实际价值?搜索算子支持哪些语法?

本次分享主要介绍面向数据加工DSL的一项编译优化:搜索算子语义等价转换。e_search()是灵活的语义丰富的搜索算子,通过简洁的DSL即可实现复杂的搜索需求。搜索过滤是日志处理的基本功能,在数据加工作业中搜索算子被极高频使用(数据加工共200+算子,搜索算子e_search()使用频度排名top 5)。搜索算子支持哪些语法?搜索算子语义等价转换是怎么实现的?有哪些实际价值?

搜索算子支持哪些语法?

# 全文
e_search("active error")     # 全文:两个子串是OR关系,进行搜索。
e_search('"active error"')   # 全文:一个子串搜索。

# 字段:字符串
e_search("status: active")         # 单词搜索。
e_search('author: "john smith"')   # 带空格子串搜索。
e_search('field: active error')   # 相当于field:active OR "error"。

# 完全匹配
e_search('author== "john smith"')  

# 通配符搜索,星号(*)匹配零个或多个字符,问号(?)匹配一个字符。
e_search("status: active*test")    # active*test中仅包含星号(*),可以不使用双引号("")包裹。
e_search("status: active?good")    # active?good中仅包含问号(?),可以不使用双引号("")包裹。
e_search("status== ac*tive?good")  # 完全匹配。

# 搜索值转义,星号(*)或问号(?)需要使用反斜线(\)转义。
e_search('status: "\*\?()[]:="')  # \*\?()[]:=中包含特殊字符,需要使用双引号("")包裹,除了星号(*)、问号(?)和反斜线(\)需要转义外,其他不用转义。
e_search("status: active\*test")  # active\*test中仅包含星号(*),可以不使用双引号("")包裹。
e_search("status: active\?test")  # active\?test中仅包含问号(?),可以不使用双引号("")包裹。

# 字段名转义
e_search("\*\(1+1\)\?: abc")                  # 字段名不能用双引号("")包裹,特殊字符用反斜线(\)转义。
e_search("__tag__\:__container_name__: abc")  # 用反斜线(\)转义。
e_search("中文字段: abc")                     # 直接写中文。

# 正则匹配
e_search('content~="正则表达式"')   # 正则匹配。

# 数字
e_search('count: [100, 200]')   # >=100 and <=200
e_search('count: [*, 200]')     # <=200
e_search('count: [200, *]')     # >=200
e_search('age >= 18')           # >= 18
e_search('age > 18')            # > 18

# 使用关系运算符
e_search("abc OR xyz")    # 关系运算符不区分大小写,OR和or效果一样。
e_search("abc and (xyz or zzz)")
e_search("abc and not (xyz and not zzz)")
e_search("abc && xyz")    # and
e_search("abc || xyz")    # or
e_search("abc || !xyz")   # or not

e_search使用说明:

https://help.aliyun.com/document_detail/125398.htm?spm=a2c4g.11186623.0.0.5cd145e6edi73h#title-k4j-izy-ojw

查询字符串语法:

https://help.aliyun.com/document_detail/129383.htm?spm=a2c4g.11186623.0.0.7cbc45e6c8xylM#concept-1597612

搜索算子语义等价转换是怎么实现的?

搜索算子语法支持较为丰富,原方案采用遍历AST(抽象语法树,Abstract Syntax Tree)的方式,根据当前的标识符类型执行对应操作。上述设计也就是常说的“解析执行”方案,由于每次都需要 “判断标识符类型”,执行效率较慢。“搜索算子语义等价转换”设计方案相当于在执行前提前分析AST,避免了重复“判断标识符类型”,直接搜索表达式对应操作,由此“编译执行”设计方案不仅功能上兼容了“解析执行”方案,而且执行效率较快。

搜索算子语义等价转换主要包含如下步骤:

  • 词法语法分析

采用词法语法解析工具将数据加工作业的DSL解析并改写为语义一致且具有父子关系的AST。

AST准确表示了搜索算子的语义,并且,通过AST的节点层级关系表示了嵌套语义。

搜索算子e_search的Antlr4语法文件,如下:

/**
 * alibab sls etl dsl
 * author lanyan_wb
 * java -classpath antlr-4.7.2-complete.jar org.antlr.v4.Tool -Dlanguage=Cpp DSL.g4
*/

grammar DSL;

//
searchExpression
    :   logicalOrExpression
    ;

//
logicalOrExpression
    :   logicalAndExpression
    |   logicalOrExpression logicOr logicalAndExpression
    |   logicalOrExpression logicalAndExpression
    ;

logicOr
    :   '||'
    |   Or
    ;

//
logicalAndExpression
    :   logicalNotExpression
    |   logicalAndExpression logicAnd logicalNotExpression
    ;

logicAnd
    :   '&&'
    |   And
    ;

//
logicalNotExpression
    :   logicNot fieldSearchExpression
    |   fieldSearchExpression
    ;

logicNot
    :   '!'
    |   Not
    ;

//
fieldSearchExpression
    :   numberCompareExpression
    |   numberRangeCompareExpression
    |   singleFieldSearchExpression
    |   fullFieldSearchExpression
    ;


// field_name("field") + (COLON | EQ_FULL | EQ_REG | EQ)
singleFieldSearchExpression
    :   fieldIdentifier singleFieldSearchOperator primaryFieldSearchExpression
    ;

singleFieldSearchOperator
    :   COLON
    |   EQ_FULL
    |   EQ_REG
    |   EQ
    ;

fullFieldSearchExpression
    :   primaryFieldSearchExpression
    ;

primaryFieldSearchExpression
    :   wordExpression
    |   stringExpression
    |   LPAR searchExpression RPAR
    ;

// field_name("field") + (EG | EL | GT | LT | EQ) + number
numberCompareExpression
    :   fieldIdentifier numberCompareOpertor Number
    ;

numberCompareOpertor
    :   EG
    |   EL
    |   GT
    |   LT
    |   EQ
    ;


// field_name("field") + (COLON | EQ) + range_search
numberRangeCompareExpression
    :    fieldIdentifier numberRangeOperator LBRACK NumberRange RBRACK
    ;

numberRangeOperator
    :   COLON
    |   EQ
    ;


fieldIdentifier
    :   Or
    |   And
    |   Not
    |   To
    |   Number
    |   ValidWord
    ;

wordExpression
    :   Or
    |   And
    |   Not
    |   To
    |   Number
    |   ValidWord
    ;

stringExpression
    :   String
    ;

COLON: ':';
LBRACK: '[';
RBRACK: ']';
LBRACE: '{';
RBRACE: '}';
TILDE: '~';
CARAT: '^';

EG: '>=';
EL: '<=';
EQ_FULL: '==';
EQ_REG: '~=';
GT: '>';
LT: '<';
EQ: '=';

LPAR: '(';
RPAR: ')';

Or: [Oo][Rr];
And: [Aa][Nn][Dd];
Not: [Nn][Oo][Tt];
To: [Tt][Oo];

Number
    :   [+-]? [0-9]+ '.'? [0-9]* ([eE] [+-]? [0-9]+)?
    ;

NumberRange
    :   RangeNumber [ \t]* ',' [ \t]* RangeNumber
    ;

fragment
RangeNumber
    :   Number
    |   '*'
    ;

ValidWord
    :   ([\u0800-\u9fa5a-zA-Z0-9*?_+.,-] | '\\' ([\u0800-\u9fa5a-zA-Z0-9] | [+\-!(){}^"~*?:@#,] | '[' | ']' | '||' | '&&' ) )+
    ;

String
    :   '"' ('\\"' | ~["\n\r])* '"'
    ;

Whitespace
    :   [ \t]+ -> skip
    ;

  • 高频场景语义转换

高频操作主要分为“全文搜索”、“否逻辑运算”、“与否逻辑运算”、“字段搜索”。其中,“全文搜索”为单目运算,“否逻辑运算”为二目运算,“与或逻辑运算”和“字段搜索”为三目运算。

判断当前处理的表达式是几目运算,并分别执行对应的操作:

如果为单目运算,则转换为“全文搜索”。

如果为二目运算,则转换为“否逻辑运算”。

如果为三目运算,则判断当前操作符是否为“And/Or”,如果是,则转换为“与或逻辑运算”,否则,判断当前操作符是否为“==/:/=/~=”,如果是,则转换为“字段搜索”。

其他情况,表示转换失败。

由于搜索算子e_search()支持嵌套语法,因此在执行上述操作时,“否逻辑运算”和“与或逻辑运算”需要执行上述转换以处理嵌套的子表达式。

有哪些实际价值?

搜索算子的语义等价转换均由后台编译器自动实现,用户无需参与。通过搜索算子的语义等价转换编译优化,“全文搜索”、“字段子串搜索”和“字段相等判断”会有5倍的性能提升,“字段正则匹配”会有2倍的性能提升。进而优化了事件吞吐率和实时性,有效降低了客户数据加工作业出现延时的概率。并且,减少了服务器使用数量,节省了运营成本。

注意:搜索算子语义等价转换只能解决一些高频优化操作,较优数据结构的转换后面会另起一篇文章详细说明。

本次分享承接“数据加工DSL编译优化:公共子表达式删除”,均隶属“数据加工性能优化”专栏。相关链接:

数据加工概述:https://help.aliyun.com/document_detail/125384.html

数据加工DSL简介:https://help.aliyun.com/document_detail/125439.html

数据加工DSL函数总览:https://help.aliyun.com/document_detail/159702.html

数据加工架构设计:https://topic.atatech.org/articles/208924

数据加工DSL编译优化:公共子表达式删除:https://ata.alibaba-inc.com/articles/214189

联系方式

对我们工作感兴趣的,可以通过如下方式了解更多,谢谢关注!

相关实践学习
日志服务之数据清洗与入湖
本教程介绍如何使用日志服务接入NGINX模拟数据,通过数据加工对数据进行清洗并归档至OSS中进行存储。
相关文章
|
2月前
|
存储 数据挖掘 机器人
使用LOTR合并检索提高RAG性能
RAG结合了两个关键元素:检索和生成。它首先使用语义搜索等高级技术来浏览大量数据,包括文本、图像、音频和视频。RAG的本质在于它能够检索相关信息,然后作为下一阶段的基础。生成组件利用大型语言模型的能力,解释这些数据块,制作连贯的、类似人类的响应。与传统的生成模型相比,这个过程确保RAG系统可以提供更细致和准确的输出。
164 2
|
10月前
|
算法 索引
阿里云 Elasticsearch 使用 RRF 混排优化语义查询结果对比
Elasticsearch 从8.8版本开始,新增 RRF,支持对多种不同方式召回的多个结果集进行综合再排序,返回最终的排序结果。之前 Elasticsearch 已经分别支持基于 BM25 的相关性排序和向量相似度的召回排序,通过 RRF 可以对这两者的结果进行综合排序,可以提升排序的准确性。
1874 0
|
17天前
|
存储 NoSQL Redis
深入解析RedisSearch:全文搜索的新维度
深入解析RedisSearch:全文搜索的新维度
|
2月前
|
机器学习/深度学习 人工智能 运维
人工智能平台PAI 操作报错合集之请问Alink的算法中的序列异常检测组件,是对数据进行分组后分别在每个组中执行异常检测,而不是将数据看作时序数据进行异常检测吧
阿里云人工智能平台PAI (Platform for Artificial Intelligence) 是阿里云推出的一套全面、易用的机器学习和深度学习平台,旨在帮助企业、开发者和数据科学家快速构建、训练、部署和管理人工智能模型。在使用阿里云人工智能平台PAI进行操作时,可能会遇到各种类型的错误。以下列举了一些常见的报错情况及其可能的原因和解决方法。
|
8月前
|
机器学习/深度学习 自然语言处理 安全
【网安专题11.8】14Cosco跨语言代码搜索代码: (a) 训练阶段 相关程度的对比学习 对源代码(查询+目标代码)和动态运行信息进行编码 (b) 在线查询嵌入与搜索:不必计算相似性
【网安专题11.8】14Cosco跨语言代码搜索代码: (a) 训练阶段 相关程度的对比学习 对源代码(查询+目标代码)和动态运行信息进行编码 (b) 在线查询嵌入与搜索:不必计算相似性
213 0
|
2月前
|
分布式计算 Java Hadoop
MapReduce编程:检索特定群体搜索记录和定义分片操作
MapReduce编程:检索特定群体搜索记录和定义分片操作
45 0
|
9月前
|
机器学习/深度学习 自然语言处理 算法
文本数据处理:基本技巧与实例分析
文本数据处理:基本技巧与实例分析
247 0
|
分布式计算 算法 大数据
白话Elasticsearch45-深入聚合数据分析之易并行聚合算法,三角选择原则,近似聚合算法
白话Elasticsearch45-深入聚合数据分析之易并行聚合算法,三角选择原则,近似聚合算法
73 0
|
分布式计算 Java Hadoop
白话Elasticsearch08-深度探秘搜索技术之基于boost的细粒度搜索条件权重控制
白话Elasticsearch08-深度探秘搜索技术之基于boost的细粒度搜索条件权重控制
128 0
|
大数据 开发者
聚合操作_多维聚合_编写代码 | 学习笔记
快速学习聚合操作_多维聚合_编写代码
96 0
聚合操作_多维聚合_编写代码 | 学习笔记