黑客24小时在线接单的网站

黑客24小时在线接单的网站

Sentry 监控 - Snuba 数据中台架构(Query Processing 简介)

本文转载自微信公众号「黑客下午茶」,作者少 。请联系黑客下午茶微信官方账号转载本文。

Snuba 有一个查询处理管道,首先是 Snuba 查询语言( legacy 和 SnQL)解析为 AST,然后在 Clickhouse 上执行 SQL 查询。AST 在应用查询处理转换中执行多次传输。

管道处理有两个主要目标:优化查询,防止危险的查询。

在数据模型中,查询处理流水线分为逻辑部分,用于产品相关处理,物理部分专注于优化查询。

逻辑部分包括查询和验证步骤,以确保它与数据模型匹配或应用自定义函数。物理部分包括升级标签等(promoting tags)并选择预聚合视图(pre-aggregated view)为查询提供服务等步骤。

查询处理阶段

本节介绍了上述各阶段的代码和示例,并提供了一些提示。

Legacy 和 SnQL 解析器

Snuba 支持两种语言,传统两种语言JSON 的语言和新名称SnQL 语言。除了传统语言不支持的连接和复合查询外,查询管道不会改变是否使用一种或另一种语言。

Snuba 支持两种语言,一种是基于 JSON 的旧语言,另一种叫 SnQL 新语言。无论使用哪种语言,查询处理管道都不会改变,除了遗留语言不支持的连接和复合查询。

它们都产生逻辑查询AST,以下数据结构表示查询。

                   
  • https://github.com/getsentry/snuba/tree/master/snuba/query

基于 JSON 语言旧分析器源代码:

                   
  • https://github.com/getsentry/snuba/blob/master/snuba/query/parser/__init__.py

SnQL 解析器:

                   
  • https://github.com/getsentry/snuba/tree/master/snuba/query/snql

查询验证(Query Validation)

现阶段确保查询能够运行(在大多数情况下,我们还没有捕获所有可能的无效查询)。本阶段的职责是在无效查询的情况下返回 HTTP400,并向用户提供适当的有用消息。

分为两个子阶段:一般验证(general validation)具体验证实体(entity specific validation)。

一般验证由一组检查组成,在分析器生成查询后立即应用于每个查询。QueryEntity 发生在函数中。这包括防止别名阴影(alias shadowing)与函数签名验证(function signature validation)等验证。

                   
  • QueryEntity:https://github.com/getsentry/snuba/blob/master/snuba/query/parser/__init__.py#L91

每个实体也可以以必要列的形式提供一些验证逻辑。这发生在 class Entity(Describable,ABC):。这允许查询处理拒绝 project_id 查询没有条件或时间范围。

                   
  • https://github.com/getsentry/snuba/blob/master/snuba/datasets/entity.py#L46-L47

逻辑查询处理器(Logical Query Processors)

查询处理器无状态转换,接收查询对象(及其 AST)并在当地进行转换。这是为逻辑处理器实现的接口。在逻辑阶段,每个实体提供按顺序应用的查询处理器。常用的用途是 apdex 或时间序列处理器等自定义函数(time series processor)那样的计时。

                   
  • apdex: https://github.com/getsentry/snuba/blob/10b747da57d7d833374984d5eb31151393577911/snuba/query/processors/performance_expressions.py#L12-L20
  •                
  • time series processor:https://github.com/getsentry/snuba/blob/master/snuba/query/processors/timeseries_processor.py

查询处理器不应依赖于前后执行的其他处理器,而应相互独立。

存储选择器(Storage Selector)

如 Snuba 在数据模型中,每个实体可以定义多个存储。多个存储代表多个表,物化视图可以由于性能原因定义(materialized views),因为某些视图可以更快地响应某些查询。

在逻辑处理阶段(完全基于实体)结束时,存储选择器可以检查和查询,并为查询选择合适的存储。存储选择器在物理数据模型中定义并实现此接口。一个例子是 Errors 实体有两个存储器,一个用于一致查询(它们从路由到写入事件的相同节点),另一个只包括我们没有写入的副本,以服务于大多数查询。这减少了我们写入节点的负载。

                   
  • https://github.com/getsentry/snuba/blob/master/snuba/datasets/storage.py#L155-L165

查询转换器(Query Translator)

不同的 storage 有不同的 schema(这些反映了 clickhouse 表或视图schema)。它们通常不同于实体模型,最明显的例子是标签 tags[abc] 在 clickhouse 不存在,其中访问标签看起来像 tags.values[indexOf(tags.key,'abc')]。

选择 storage 之后,需要将查询转化为物理查询。Translator 是一个基于规则的系统,规则由实体(针对每个 storage)定义并按顺序应用。

与查询处理器相反,翻译规则在查询中没有完整的上下文,只能翻译单个表达式。这使我们能够轻松地编写翻译规则,并跨实体重用它们。

这些是 transactions 实体转换规则。

                   
  • https://github.com/getsentry/snuba/blob/master/snuba/datasets/entities/transactions.py#L33-L81

物理查询处理器(Physical Query Processors)

与逻辑查询处理器相比,物理查询处理器的工作模式非常相似。它们的界面非常相似,具有相同的语义。不同之处在于它们操作物理查询,因此它们主要是为优化而设计的。例如,处理器在标签上找到相同的条件,并将其替换为标签哈希图(布隆过滤索引)上的等效条件,以使过滤操作更快。

                   
  • https://github.com/getsentry/snuba/blob/master/snuba/query/processors/mapping_optimizer.py

查询拆分器(Query Splitter)

通过将某些查询分为多个单独的 Clickhouse 查询并组合每个查询的结果,可以以优化的方式执行某些查询。

两个例子是时间拆分和列拆分。两者都在下面的文件中。

                   
  • https://github.com/getsentry/snuba/blob/master/snuba/web/split.py

时间拆分(Time splitting)在可变的时间范围内将一个查询(不包括聚合和正确排序)分为多个查询,并在获得足够的结果后按顺序停止执行。

列拆分(Column splitting)拆分筛选和列获取。Clickhouse 加载较少的列,然后通过第二个查询,仅为第一个查询筛选行获得缺失列。

查询格式化器(Query Formatter)

该组件仅将查询格式化为 Clickhouse 查询字符串。

复合查询处理

以上讨论仅适用于简单查询和复合查询(连接和包含子查询遵循稍有不同的路径)。

上述简单查询管道不适用于连接查询或包含子查询。为了使工作发挥作用,每一步都必须考虑连接查询和子查询,这将增加过程的复杂性。

为了解决这个问题,我们将每个连接查询转换为多个简单的子查询连接。每个子查询都是一个简单的查询,可以通过上述管道询。这也是操作 Clickhouse 连接(join)因为它允许我们在连接前使用过滤器。

此类查询的查询处理管道由几个与上述内容相关的附加步骤组成。

子查询生成器(Subquery Generator)

组件采用简单的 SnQL 连接查询,并为连接中的每个表创建一个子查询。

表达式下推(Expressions Push Down)

上一步生成的查询将是一个有效的连接,但效率非常低。这一步基本上是连接优化器(join optimizer),它将所有可以成为子查询部分的表达式推入子查询。Clickhouse join 发动机不执行任何表达式的下推,因此由 Snuba 优化查询。

简单查询处理管道(Simple Query Processing Pipeline)

这与从逻辑查询验证到物理查询处理器的管道相同。

连接优化(Join Optimizations)

处理结束时,我们可以优化整个复合查询应用,比如 join 转换为 Semi Join。

   
  • 评论列表:
  •  弦久顾执
     发布于 2022-06-04 09:05:41  回复该评论
  • 用一种或另一种语言。Snuba 支持两种语言,一种是基于 JSON 的旧语言,另一种叫 SnQL 新语言。无论使用哪种语言,查询处理管道都不会改变,除了遗留语言不支持的连接和复合查询。它们都产生逻辑查询AST,以下
  •  余安几钵
     发布于 2022-06-04 05:55:16  回复该评论
  • L20                time series processor:https://github.com/getsentry/snuba/blob/master/snuba/query/processors/timeseries_processor.py查询处理器不应依赖
  •  酒奴南戈
     发布于 2022-06-04 09:17:47  回复该评论
  • 另一个只包括我们没有写入的副本,以服务于大多数查询。这减少了我们写入节点的负载。                https://github.com/getsentry/snuba/blob/maste

发表评论:

Powered By

Copyright Your WebSite.Some Rights Reserved.