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

[[428154]]

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

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。

 

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/122255.html<

(0)
运维的头像运维
上一篇2025-02-22 06:29
下一篇 2025-02-22 06:30

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注