Query Filters

任何数据库系统的一项关键功能是使用某种形式的过滤来获取完整数据集的子集。从版本 1.x 开始,OpenTSDB 提供了过滤功能,具有从 2.2 及更高版本开始的扩展功能。目前,过滤器目前在标签值上运行。这意味着在获取数据时,必须完全按照数据库中显示的所有度量标准和标记键进行指定。

Example Data

如下面对每个过滤器的说明,将使用以下数据集。它由一个具有多个时间序列的 Metrics 组成,这些时间序列定义在各种标签上。例如,* T1 *仅给出一个数据点。

TS#MetricTags值@ T1
1sys.cpu.systemdc=dal host=web013
2sys.cpu.systemdc=dal host=web022
3sys.cpu.systemdc=dal host=web0310
4sys.cpu.systemhost=web011
5sys.cpu.systemhost=web01 owner=jdoe4
6sys.cpu.systemdc=lax host=web018
7sys.cpu.systemdc=lax host=web024

Grouping

分组,也称为* group-by *,是使用所需的聚合函数和过滤器将多个时间序列合并为一个的过程。默认情况下,OpenTSDB 按度量标准对所有内容进行分组,因此,如果查询返回的时间序列为sum的 10 个时间序列,则随着时间的推移,所有 10 个时间序列将加在一起,以得出一个值。有关如何合并时间序列的详细信息,请参见Aggregation

为避免分组和获取每个基础时间序列而没有任何聚合,请使用版本 2.2 中包含的none聚合器。另外,您可以使用 OpenTSDB 2.2 及更高版本在每个过滤器的基础上禁用分组。有关如何操作,请参阅 API 文档。

OpenTSDB 1.x-2.1

在最初的 OpenTSDB 版本和 2.1 以下版本中,只有两种类型的过滤器可用,并且已隐式配置它们以进行分组。允许的两个运算符是:

  • **** -星号(或通配符*)将为检测到的每个唯一标记值返回单独的结果。例如。如果标记键hostweb01web02配对,则将发出两个组,一个在web01上,一个在web02上。

  • | -管道(或* literal_or )将为指定的确切标记值返回 only *单独的结果。即它将仅匹配具有给定标签值的时间序列,并在每个匹配项上进行分组。

每个查询可以提供多个过滤器,并且结果始终“与”在一起。这些过滤器仍可在 2.x 及更高版本中使用。

Examples

以下示例使用 v1 HTTP URI 语法,其中m参数由聚合器,冒号,然后由等号分隔的括号中的度量和标记过滤器组成。

范例 1: http://host:4242/q?start=1h-ago&m=sum:sys.cpu.system{host=web01}

包括时间序列TagsAggregated Tags值@ T1
1, 4, 5, 6host=web01 16

在这种情况下,聚合标签集将为空,因为时间序列 4 和 5 的标签与整个标签集并不相同。

范例 2: http://host:4242/q?start=1h-ago&m=sum:sys.cpu.system{host=web01,dc=dal}

包括时间序列TagsAggregated Tags值@ T1
1host=web01,dc=dal 3

范例 3: http://host:4242/q?start=1h-ago&m=sum:sys.cpu.system{host=*,dc=dal}

包括时间序列TagsAggregated Tags值@ T1
1host=web01,dc=dal 3
2host=web02,dc=dal 2
3host=web03,dc=dal 10

这次,我们为主机提供了*,并为dc提供了明确匹配。这将对host标签键进行分组,并为每个唯一的主机标签值返回一个时间序列,在本例中为 3 个序列。

范例 4: http://host:4242/q?start=1h-ago&m=sum:sys.cpu.system{dc=dal|lax}

包括时间序列TagsAggregated Tags值@ T1
1, 2, 3dc=dalhost15
6, 7dc=laxhost12

此处|运算符仅用于匹配查询中提供的dc标记键的值。因此,TSD 将使用这些值将任何时间序列分组在一起。 host标签将移到“聚合标签”列表中,因为该集中的每个时间序列都有一个host标签,并且标签键有多个值。

Warning

由于这些过滤器是有限的,因此,如果用户编写诸如 #1#4#5 之类的时间序列,则由于汇总可能具有一个共同点的时间序列,可能会返回意外结果标签,但可以更改其他标签。 2.3 和 Explicit Tags 可以解决此问题。

OpenTSDB 2.2

在 OpenTSDB 2.2 中,添加了更灵活的过滤器框架,该框架允许禁用分组以及其他过滤器类型,例如正则表达式和通配符。过滤器框架是可插入的,以允许绑定到外部系统,例如资产 Management 或供应系统。

允许在同一标签键上使用多个过滤器,并在处理时将它们“与”在一起,例如如果我们有两个过滤器host=literal_or(web01)host=literal_or(web02),则查询将始终返回空。如果同一标签键包含两个或多个过滤器,并且一个过滤器启用了分组依据,而另一个未启用,则对于该标签键上的所有过滤器,分组依据将有效。

Warning

某些类型的过滤器可能会导致查询执行速度比其他过滤器慢,尤其是regexpwildcard和不区分大小写的过滤器。在从存储中获取数据之前,将对过滤器进行处理以创建基于 UID 的数据库过滤器,因此使用区分大小写的literal_or过滤器总是比regexp更快,因为我们可以将字符串解析为 UID 并将其发送到存储系统以进行过滤。相反,如果您要求通过正则表达式,通配符或前缀过滤使用正则表达式或通配符,则 TSD 必须使用标记键 UID 从存储中检索所有行,然后对于每个唯一行,将 UID 解析为字符串,然后对结果。同样,具有大量 Literals 的过滤器集将在存储后进行处理,以避免为后备存储创建大量的过滤器以进行处理。该限制默认为4096,可以通过tsd.query.filter.expansion_limit参数进行配置。

Explicit Tags

从 2.3 及更高版本开始,如果您知道给定度量标准的所有标记键,则可以使用explicitTags功能极大地改善查询延迟。该标志有两个好处:

  • 对于具有高基数的 Metrics,后端可以切换到更有效的查询以从存储中获取较小的数据子集。 (特别是在 2.4 中)

  • 对于具有变化标签的度量,可以将其用于避免汇总不应包含在最终结果中的时间序列。

显式标签将构建底层存储查询,该查询仅使用给定标签键获取那些行。这样可以使数据库跳过不相关的行并在更少的时间内回答。

Examples

以下示例使用 v2 HTTP URI 语法,其中m参数由聚合器,冒号,explicit_tags URI 标志,然后由等号分隔的括号中的度量和标记过滤器组成。

范例 1: http://host:4242/api/query?start=1h-ago&m=sum:explicit_tags:sys.cpu.system{host=web01}

包括时间序列TagsAggregated Tags值@ T1
4host=web01 1

这解决了标签键不一致的问题,使我们只能选择时间序列*#4 *。

范例 2: http://host:4242/api/query?start=1h-ago&m=sum:explicit_tags:sys.cpu.system{host=*}{dc=*}

包括时间序列TagsAggregated Tags值@ T1
1, 6host=web01dc11
2, 7host=web02dc6
3host=web03,dc=dal 10

该查询使用 v2 URI 语法,通过将其放在第二组花括号中来避免对dc标记键进行分组。这使我们仅在同时将host值分组时,仅过滤同时具有hostdc标记键的时间序列。它跳过时间序列*#4 #5 *。

Note

使用 HBase(0.98 和更高版本)或 Bigtable 时,请确保在配置中启用了tsd.query.enable_fuzzy_filter(默认情况下启用)。后端有一个特殊的过滤器,它使我们可以向前跳到查询所需的行,而不是遍历每个行键并比较正则表达式。

Note

对于 2.4,TSDB 将向后端发出多个get请求,而不是使用扫描器。这样可以将查询时间减少多种因素,尤其是对于高基数时间序列而言。但是,过滤器必须仅由literal_or组成。

内置 2.x 过滤器

以下列表是 OpenTSDB 附带的内置过滤器。可以将其他过滤器作为插件加载。每个标题都是要在 URI 或 JSON 查询中使用的过滤器的type。编写 URI 查询时,通过将过滤器名称放在标记键的等号之后并将过滤器值放在括号中来使用过滤器。例如。 {host=regexp(web[0-9]+.lax.mysite.com)}。对于 JSON 查询,只需将过滤器名称用作type参数,并将过滤器值用作filter参数,例如

{
  "type": "regexp",
  "filter": "web[0-9]+.lax.mysite.com",
  "tagk": "host",
  "groupBy": false
}

下面的示例使用 URI 语法。

literal_or

接受单个 Literals 值或|竖线分隔的值列表,并以区分大小写的方式返回与结果匹配的任何时间序列。这是一个非常有效的过滤器,因为它可以将字符串解析为 UID,并将其发送到存储层进行预过滤。在 SQL 中,这类似于IN=谓词。

Examples

  • host=literal_or(web01|web02|web03)在 SQL 中:WHERE host IN ('web01', 'web02', 'web03')

  • host=literal_or(web01)在 SQL 中:WHERE host = 'web01'

ilteral_or

literal_or相同,但不区分大小写。请注意,这与字面量一样效率不高,因为它必须对存储中的所有行进行后处理。

not_literal_or

区分大小写的literal_or将返回与指定值列表不匹配的系列。高效,因为可以通过存储对其进行预处理。

not_iliteral_or

不区分大小写的not_literal_or

wildcard

提供区分大小写的后缀,前缀,中缀和多中缀过滤。通配符是星号*。可以使用多个通配符。如果仅给出星号,则过滤器有效地返回包含标签键的任何时间序列(并且是可以进行预处理的高效过滤器)。在 SQL 领域中,这类似于LIKE谓词,但具有更大的灵 Active。

Examples

  • host=wildcard(*mysite.com)在 SQL 中:WHERE host='%mysite.com'

  • host=wildcard(web*)

  • host=wildcard(web*mysite.com)

  • host=wildcard(web*mysite*)

  • host=wildcard(*)这等效于按运算符的 v1 基本组,并且非常有效。

iwildcard

wildcard相同,但不区分大小写。

regexp

使用 POSIX 兼容的正则表达式进行过滤,然后从存储中提取数据。该过滤器使用 Java 的内置正则表达式操作。根据所使用的查询方法,请小心转义特殊字符。

Examples

  • regexp(web.*)在 SQL 中:WHERE host REGEXP 'web.*'

  • regexp(web[0-9].mysite.com)

Loaded Filters

要显示 OpenTSDB 2.2 和更高版本中已加载的筛选器,请调用 HTTP /api/config/filters端点。这将列出已加载的插件以及说明和示例用法。

Plugins

当开发人员添加插件时,我们将在此处列出它们。

要开发插件,只需扩展net.opentsdb.query.filter.TagVFilter类,根据Plugins文档创建 JAR 并将其放在您的 plugins 目录中。在启动时,TSD 将搜索并加载该插件。如果实现存在错误,则 TSD 将不会启动,并将记录异常。