系列

Snuba 有一个查询处理管道,首先将 Snuba 查询语言( legacySnQL)解析为 AST,然后在 Clickhouse 上执行 SQL 查询。在这两个阶段之间,在 AST 上执行几次传递以应用查询处理转换。

处理管道有两个主要目标:优化查询并防止对我们的基础设施构成危险的查询。

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

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

查询处理阶段

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

Legacy 和 SnQL 解析器

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

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

它们都生成一个逻辑查询AST,该查询由下面数据结构表示。

基于 JSON 的语言旧解析器源码:

SnQL 解析器:

查询验证(Query Validation)

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

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

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

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

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

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

查询处理器不应该依赖于在之前或之后执行的其他处理器,并且应该彼此独立。

存储选择器(Storage Selector)

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

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

查询转换器(Query Translator)

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

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

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

这些是 transactions 实体的转换规则。

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

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

查询拆分器(Query Splitter)

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

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

时间拆分(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

Sentry 监控 - Snuba 数据中台架构(Query Processing 简介)的更多相关文章

  1. Sentry 监控 - Snuba 数据中台架构(SnQL 查询语言简介)

    本文描述了 Snuba 查询语言 (SnQL). 系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒 ...

  2. Sentry 监控 - Snuba 数据中台架构(Data Model 简介)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  3. Sentry 监控 - Snuba 数据中台架构(编写和测试 Snuba 查询)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  4. Sentry 监控 - Snuba 数据中台架构简介(Kafka+Clickhouse)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  5. Sentry 监控 - Snuba 数据中台本地开发环境配置实战

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  6. Sentry 监控 - 私有 Docker Compose 部署与故障排除详解

    内容整理自官方开发文档 系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Map ...

  7. Sentry 监控 - Environments 区分不同部署环境的事件数据

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  8. Sentry 监控 - Distributed Tracing 分布式跟踪

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  9. 【转】阿里架构总监一次讲透中台架构,13页PPT精华详解

    转:https://blog.csdn.net/u011323949/article/details/99542576 本文整理了阿里几位技术专家,如架构总监 谢纯良,中间件技术专家 玄难等几位大牛, ...

随机推荐

  1. BeanUtils低依赖属性拷贝测试(一)

    javabean package entity; import java.util.Date; /** * 一个测试用: * student,javaBean * @author mzy * 一个标准 ...

  2. Java程序设计学习笔记(二)

    --正则表达式    正则表达式         ^ 匹配的开始         $ 匹配的结束         [] 表示匹配任意一个字符             [asdasd]          ...

  3. SpringCloud升级之路2020.0.x版-24.测试Spring Cloud LoadBalancer

    本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 通过单元测试,我们 ...

  4. vue3.0入门(一)

    前言 最近在b站上学习了飞哥的vue教程 学习案例已上传,下载地址 使用方式 使用在线cdn 下载js文件并自托管,引入到项目后使用 使用npm安装后,用cli来构建项目 声明式渲染 Vue2需引入v ...

  5. promise加载图片

    实现一个图片的加载:设置第一张图片加载1s之后加载第二张图片: <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  6. GUI容器之布局管理器

    布局管理器 布局管理器:frame.setLayout(); 默认值为new flowLayout() 流式布局 frame.setLayout(new FlowLayout(FlowLayout.R ...

  7. 【SpringMVC】HttpMessageConverter报文信息转换器

    HttpMessageConverter HttpMessageConverter,报文信息转换器,将请求报文转换为Java对象,或将Java对象转换为响应报文 HttpMessageConverte ...

  8. noip模拟测试50

    考试过程:开题顺序1,2,3,做T1的时候我想到了要求的东西,就是分成尽量少的段使得每段之和>=k,但是我不会求,就打了个暴力走了,然后看T2,这题我觉得和之前做过的一道题比较像,因为我觉得\( ...

  9. autoCAD绘制简单三维立体图形

    第一步: 首先绘制一个简单的(封闭的)二维图形: 第二步: 变换观察视角,比如修改为 变换后的视角: 第三步: 选中闭合图形边框,使用组合键"ctrl + shift + E",然 ...

  10. PULPino datasheet中文翻译并给了部分论文注释(前四章:Overview、Memory Map、CPU Core、Advanced Debug Unit)

    参考: (1).PULPino datasheet:https://github.com/pulp-platform/pulpino/blob/master/doc/datasheet/datashe ...