Documentation

InfluxQL 内部参考

了解 InfluxQL 的实现,以理解结果是如何处理的以及如何创建高效的查询:

查询生命周期

  1. InfluxQL 查询字符串被分解为令牌,然后解析成抽象语法树(AST)。这是查询本身的代码表示。

  2. 抽象语法树被传递给 QueryExecutor,该组件将查询指向适当的处理程序。例如,与元数据相关的查询由元服务执行,而 SELECT 语句则由分片本身执行。

  3. 查询引擎然后确定与SELECT语句的时间范围匹配的分片。从这些分片中,为语句中的每个字段创建迭代器。

  4. 迭代器被传递给发射器,它会处理这些迭代器并合并结果点。发射器的工作是将简单的时间/值点转换为返回给客户端的更复杂的结果对象。

理解迭代器

迭代器提供了一种简单的接口,用于循环遍历一组点。 例如,这是一个用于浮点数的迭代器:

type FloatIterator interface {
    Next() *FloatPoint
}

这些迭代器是通过 IteratorCreator 接口创建的:

type IteratorCreator interface {
    CreateIterator(opt *IteratorOptions) (Iterator, error)
}

IteratorOptions提供有关字段选择、时间范围和维度的参数,这些参数可以在规划迭代器时由迭代器创建者使用。IteratorCreator接口在许多级别上使用,例如ShardsShardEngine。这允许在适用时进行优化,例如返回预计算的COUNT()

迭代器不仅仅是用于从存储中读取原始数据。迭代器可以被组合,以便为输入迭代器提供额外的功能。例如,DistinctIterator可以计算输入迭代器每个时间窗口的不同值。或者,FillIterator可以生成输入迭代器中缺失的额外点。

这种组合也很适合聚合。例如,像这样的语句:

SELECT MEAN(value) FROM cpu GROUP BY time(10m)

在这种情况下,MEAN(value) 是一个 MeanIterator,它包装了来自底层分片的迭代器。然而,如果我们可以添加一个额外的迭代器来确定均值的导数:

SELECT DERIVATIVE(MEAN(value), 20m) FROM cpu GROUP BY time(10m)

游标

A 游标 通过元组 (时间, 值) 为单个系列 (测量, 标签集和字段) 标识数据。游标遍历存储为日志结构合并树的数据,并处理跨级别的去重,已删除数据的 tombstones,以及合并缓存 (预写日志)。游标按升序或降序对 (time, value) 元组进行排序。

例如,一个评估1,000个系列在3个分片上的一个字段的查询构建了至少3,000个游标(每个分片1,000个)。

辅助字段

因为 InfluxQL 允许用户使用选择函数,比如 FIRST(), LAST(), MIN()MAX(), 引擎必须提供一种方法来同时返回与选择点相关的数据。

让我们来看看以下查询:

SELECT FIRST(value), host FROM cpu GROUP BY time(1h)

我们选择每小时出现的第一个 value,但我们也希望检索与该点相关的 host。由于 Point 类型仅为效率指定一个单一的类型 Value,我们将 host 推入点的辅助字段。这些辅助字段附加到点上,直到它被传递给发射器,在那里字段被分离到它们自己的迭代器中。

内置迭代器

有许多辅助迭代器可以让我们构建查询:

  • 合并迭代器 - 这个迭代器将一个或多个迭代器组合成一个新的相同类型的迭代器。这个迭代器保证在开始下一个窗口之前,窗口内的所有点都会被输出,但不保证窗口内的顺序。这允许快速访问不需要更强排序保证的聚合查询。

  • 排序合并迭代器 - 该迭代器还将一个或多个迭代器组合成一个相同类型的新迭代器。然而,该迭代器保证每个点的时间顺序。这使得它比MergeIterator慢,但这种顺序保证对于返回原始数据点的非聚合查询是必需的。

  • 限制迭代器 - 这个迭代器限制每个名称/标签组的点数。 这是LIMIT & OFFSET 语法的实现。

  • 填充迭代器 - 如果输入迭代器中缺少点,则该迭代器会注入额外的点。它可以提供 null 点、带有前一个值的点或带有特定值的点。

  • 缓冲迭代器 - 该迭代器提供了将一个点“未读”回缓冲区的能力,以便下次可以再次读取。这在窗口处理上被广泛使用,以提供前瞻性。

  • 减少迭代器 - 这个迭代器对窗口中的每个点调用一个减少函数。当窗口完成时,该窗口的所有点将被输出。这用于简单的聚合函数,例如 COUNT()

  • 减少切片迭代器 - 该迭代器首先收集窗口中的所有点,然后一次性将它们传递给一个归约函数。结果从迭代器返回。这用于聚合函数,例如DERIVATIVE()

  • 变换迭代器 - 该迭代器对输入迭代器中的每个点调用一个变换函数。这用于执行二元表达式。

  • 去重迭代器 - 该迭代器仅输出唯一的点。它资源密集,因此仅用于小查询,例如元查询语句。

调用迭代器

InfluxQL中的函数调用分为两个层级。一些调用可以在多个层级进行包装,以提高效率。例如,一个 COUNT() 可以在分片级别执行,然后多个 CountIterator 可以与另一个 CountIterator 进行包装,以计算所有分片的计数。这些迭代器可以使用 NewCallIterator() 创建。

一些迭代器更复杂或需要在更高的层次上实现。 例如,DERIVATIVE() 函数需要首先检索窗口的所有点,然后再执行计算。 这个迭代器是由引擎本身创建的,并且从未请求由低级别创建。



Flux的未来

Flux 正在进入维护模式。您可以像现在一样继续使用它,而无需对您的代码进行任何更改。

阅读更多

InfluxDB 3 开源版本现已公开Alpha测试

InfluxDB 3 Open Source is now available for alpha testing, licensed under MIT or Apache 2 licensing.

我们将发布两个产品作为测试版的一部分。

InfluxDB 3 核心,是我们新的开源产品。 它是一个用于时间序列和事件数据的实时数据引擎。 InfluxDB 3 企业版是建立在核心基础之上的商业版本,增加了历史查询能力、读取副本、高可用性、可扩展性和细粒度安全性。

有关如何开始的更多信息,请查看:

由TSM驱动的InfluxDB Cloud