Sentry 監控 - Snuba 資料中臺架構(SnQL 查詢語言簡介)

為少 發表於 2021-11-29

Sentry 監控 - Snuba 資料中臺架構(SnQL 查詢語言簡介)

本文描述了 Snuba 查詢語言 (SnQL)。

系列

以下是 SnQL 的查詢結構:

MATCH simple | join | subquery
SELECT [expressions] | [aggregations BY expressions]
ARRAY JOIN [column]
WHERE condition [[AND | OR] condition]*
HAVING condition [[AND | OR] condition]*
ORDER BY expressions ASC|DESC [, expressions ASC|DESC]*
LIMIT expression BY n
LIMIT n
OFFSET n
GRANULARITY n
TOTALS boolean

這些查詢作為字串傳送到 /:dataset/snql 端點,編碼為以下格式的 JSON body

{
    "query": "<query>",
    "dataset": "<dataset>",
    "consistent": bool,
    "turbo": bool,
    "debug": bool,
}

資料集(dataset)通過查詢使用的 url 隱含。在 JSON 主體中,除了 query 之外的所有欄位都是可選的。

MATCH

我們的資料模型由實體圖表示。該子句標識了我們正在查詢的子圖(subgraphs)的模式。目前支援三種型別的 MATCH 子句:

Simple:

MATCH (<entity> [SAMPLE n])

這相當於我們當前的所有查詢。 這是從單個實體(事件、事務等)查詢資料。可以通過將其與實體一起新增來向查詢新增可選 sample

例如:MATCH (events)

Subquery:

MATCH { <query> }

花括號內可以是另一個完整的 SQL 查詢。子查詢的 SELECT/BY 子句中的任何內容都將使用指定的別名在外部查詢中公開。

例如:

MATCH {
    MATCH (transactions)
    SELECT avg(duration) AS avg_d BY transaction
}
SELECT max(avg_d)

Join(連線):

MATCH (<alias>: <entity> [SAMPLE n]) -[<join>]-> (<alias>: <entity> [SAMPLE n])

一個 join 代表一個多節點子圖(subgraph),是一個包含不同節點之間的多個關係的子圖。目前支援節點之間的 1..nn..11..1 有向關係。

對於 JOIN,每個實體都必須有一個別名,這是一個唯一的字串。 抽樣(Sampling)也可以應用於 join 中的任何實體。<join> 是在 Snuba 中的 Entity 中指定的字串,是一組 join 條件的簡寫。可以有多個 join 子句,用逗號分隔。

例如:

MATCH
    (e: events) -[grouped]-> (g: groupedmessage),
    (e: events) -[assigned]-> (a: groupassignee)
SELECT count() AS tot BY e.project_id, g.id
WHERE a.user_id = "somebody"

join 型別(left/inner)和 join key 是資料模型的一部分,而不是查詢的一部分。它們被硬編碼在實體程式碼中。 這是因為沒有實體可以安全地與底層資料庫的分散式版本中的任何其他實體連線。

match 子句提供給 where 子句的元組(tuple)看起來與傳統 join 子句生成的元組完全一樣:

[
    {"e.project_id": 1,  "g.id": 10}
    {"e.project_id": 1,  "g.id": 11}
    {"e.project_id": 2,  "g.id": 20}
    ...
]

SELECT .. BY

該子句指定應在輸出中返回哪些結果。如果存在聚合(aggregation),則 BY 子句中的所有內容都被視為分組 key。 如果我們想要聚合整個結果集,則可以在沒有 BY 子句的情況下進行聚合,但在這種情況下,SELECT 中只能包含聚合。即使有 BY 子句,空的 SELECT 子句也是無效的。

SELECT 子句中的表示式可以是算術函式者的任意組合。 如果查詢是 join,則每一列都必須有一個符合條件的別名,該別名與 MATCH 子句中的實體別名之一匹配。

WHERE

這是在聚合之前發生的查詢的過濾器(如 SQL 中的 WHERE)。

條件是 LHS OP RHS* 形式的中綴表示式,其中 LHSRHS字面值表示式OP 指的是一個特定的運算子比較兩個值。 這些運算子是 =!=<<=>>=INNOT INLIKENOT LIKEIS NULLIS NOT NULL 之一。請注意,當使用像 IS NULL 這樣的運算子時,RHS 是可選的。

可以使用布林關鍵字 ANDOR 組合條件。它們也可以使用 () 進行分組。

HAVING

WHERE 子句一樣工作,但它在 SELECT 子句中宣告的聚合之後應用。 所以我們可以在這裡對聚合函式的結果應用條件。

ORDER BY

指定對結果集進行排序的表示式。

LIMIT BY/LIMIT/OFFSET

不言自明,它們採用整數並在 Clickhouse 查詢中設定相應的值。 如果查詢未指定 limitoffset,它們將分別預設為 10000

GRANULARITY

一個整數,表示對基於時間的結果進行分組的粒度。

TOTALS

如果設定為 True,來自 Snuba 的響應將有一個 “totals” key,其中包含所有選定行的總值。

SAMPLE

如果 MATCH 子句中的節點未提供取樣率,則可以在此處指定。 在這種情況下,Snuba 會將 sample right 分配給查詢中的節點之一。sample 可以是介於 01 之間的浮點數,表示要取樣的行的百分比。

或者它可以是一個大於 1 的整數,表示要取樣的行數。

相關文章