On this page
Downsampling
下采样(或 signal 处理中的抽取)是降低数据采样率或分辨率的过程。例如,假设温度传感器每秒将数据发送到 OpenTSDB 系统。如果用户在一个小时的时间 Span 内查询数据,他们将收到 3,600 个数据点,可以很容易地绘制出图形。但是现在,如果用户要求整整一周的数据,他们将收到 604,800 个数据点,并且图表可能会突然变得非常混乱。使用降采样器,可以将单个时间序列在一个时间范围内的多个数据点与一个 math 函数一起汇总到一个对齐的时间戳上的单个值中。这样,我们可以将值的数量从 604,800 减少到 168.
下采样器至少需要两个组件:
间隔 -聚合值的时间范围(或* bucket )。例如,我们可以在 1 分钟或 1 小时甚至一天内汇总多个值。间隔以
<Size><Units>
格式指定,例如1h
表示 1 小时或30m
表示 30 分钟。从 2.3 *开始,现在可以使用all
间隔将时间范围内的所有结果下采样为一个值。例如。0all-sum
将对从查询开始到结束的所有值求和。请注意,仍然需要一个数字值,但它可以是零或任何其他值。汇总函数 -一种 math 函数,用于确定如何合并间隔中的值。 Aggregation文档中的聚合功能用于该功能。
例如,采用以下时间序列A
和B
。数据点涵盖 70 秒的时间 Span,即每 10 秒的值。假设我们希望将其降采样为 30 秒,因为用户正在查看更宽的时间 Span 的图表。此外,我们使用总和汇总器将这两个系列分组为一个。我们可以指定30s-sum
的降采样器,它将创建 30 秒的存储桶,并对每个存储桶中的所有数据点求和。这将为我们每个系列提供三个数据点:
Time Series | t0 | t0+10s | t0+20s | t0+30s | t0+40s | t0+50s | t0+60 |
---|---|---|---|---|---|---|---|
A | 5 | 5 | 10 | 15 | 20 | 5 | 1 |
A sum 降采样 |
5 + 5 + 10 = 20 | 15 + 20 + 5 = 40 | 1 = 1 | ||||
B | 10 | 5 | 20 | 15 | 10 | 0 | 5 |
B sum 下采样 |
10 + 5 + 20 = 35 | 15 + 10 + 0 = 25 | 5 = 5 | ||||
sum 汇总结果 |
55 | 65 | 6 |
如您所见,对于每个时间序列,我们都会生成一个合成的序列,其时间戳在间隔边界(每 30 秒)上进行归一化,因此我们将获得一个值t0
,t0+30s
和t0+60s
。每个时间间隔(或存储桶)将包含包含存储桶时间戳记(开始)和不包含以下存储桶时间戳记(结束)的数据点。在这种情况下,第一个存储桶将从t0
扩展到t0+29.9999s
。使用提供的聚合器,所有值都合并到一个新值中。例如。对于系列A
,我们将t0
,t0+10s
和t0+20s
的值相加,得出t0
的新值20
。最后,使用 sum 对查询进行分组,以便我们将两个综合时间序列相加。此时,OpenTSDB 始终在*下采样之后执行分组聚合。
Note
对于早期版本的 OpenTSDB,新数据点的实际时间戳将是该时间 Span 中每个数据点的时间戳的平均值。从 2.1 及更高版本开始,每个点的时间戳根据当前时间和下采样间隔的模与时间段的开始对齐。
根据原始数据点时间戳的其余部分除以以毫秒为单位的下采样间隔(即模数),对下采样的时间戳进行归一化。在 Java 中,代码是timestamp - (timestamp % interval_ms)
。例如,给定时间戳为1388550980000
或1/1/2014 04:36:20 UTC
,并且每小时间隔等于 3600000 毫秒,则生成的时间戳将四舍五入为1388548800000
。 UTC 4 到 5 之间的所有数据点都将在 4 AM 存储桶中结束。如果查询 1 小时内一天的数据缩减采样值,则会收到 24 个数据点(假设所有 24 小时都有数据)。
使用0all-
间隔时,结果的时间戳将是查询的开始时间。
规范化对于常见查询非常有效,例如将一天的数据缩减为 1 分钟或 1 小时。但是,如果尝试以奇数间隔(例如 36 分钟)进行下采样,则由于模数计算的性质,时间戳可能看起来有些奇怪。给定一个 36 分钟的间隔(在上面的示例中),该间隔为2160000
毫秒,结果时间戳为1388549520
或04:12:00 UTC
。 04:12
和04:48
之间的所有数据点将在单个存储桶中结束。
Calendar Boundaries
从 OpenTSDB 2.3 开始,用户可以指定基于 calendar 的下采样而不是快速模数方法。这对于报告目的(例如查看与人类时间相关的值,如几个月,几周或几天)更加有用。此外,下采样还可以考虑时区,并包含夏令时偏移和时区偏移。
要使用 calendar 边界,请查看您要查询的端点的文档。例如,V2 URI 端点具有要使用的特定时区参数(例如&timezone=Asia/Kabul
),并且通过将c
附加到间隔时间单位(如&m=sum:1dc-sum:my.metric
)来启用基于 calendar 的下采样。对于 JSON 查询,顶层使用单独的timezone
字段以及useCalendar
布尔标志。如果未提供时区,则 calendar 使用 UTC 时间。
使用 calendar 下采样时,第一个时间间隔将在指定的时区捕捉到查询年份的 1 月 1 日的 00:00:00.从那里开始,计算间隔时段,直到查询结束。每个存储桶都标有存储桶开始的时间戳记(包括首尾),并且包括所有值,直到下一个存储桶开始为止(不包括在内)。
Fill Policies
下采样通常用于对齐时间戳,以避免在进行分组时插值。因为 OpenTSDB 不会对时间对齐或应该存在的值施加约束,所以必须在查询时指定此类约束。使用降采样执行分组聚合时,如果所有序列在预期的间隔内都缺少值,则不会发出任何 signal。例如,如果某个系列每分钟从t0
到t0+6m
写入数据,但是由于某种原因,源无法在t0+3m
写入数据,则当用户期望使用 6 时,将仅序列化 5 个值。对于 2.2 及更高版本的填充策略,您现在可以选择为t0+3m
发出什么值,以便用户(或应用程序)看到特定时间戳缺少一个值,而不必弄清楚缺少哪个时间戳。每当下采样桶为空时,填充策略仅发出 sched 义的值。
可用的策略包括:
无(
none
)-默认行为,在序列化过程中不会发出缺失值,并且在聚合序列时会执行线性插值(或以其他方式指定的插值)。NaN(
nan
)-当序列中的所有值均缺失时,在序列化输出中发出NaN
。当值丢失时跳过聚合中的序列,而不是将整个分组依据转换为 NaN。Null(
null
)-与 NaN 相同的行为,除了在序列化期间它发出null
而不是NaN
之外。零(
zero
)-当缺少时间戳时,将其替换为零。零值将合并到汇总结果中。
要使用填充策略,请将策略名称(括号中的术语)附加到下采样聚合函数的末尾,并以连字符分隔。例如。 1h-sum-nan
或1m-avg-zero
。
在此示例中,我们每 10 秒报告一次数据,并且我们希望通过每 10 秒下采样并通过10s-sum-nan
使用 NaN 填充缺失值来实施 10 秒报告的查询时间策略:
Time Series | t0 | t0+10s | t0+20s | t0+30s | t0+40s | t0+50s | t0+60s |
---|---|---|---|---|---|---|---|
A | 15 | 5 | |||||
B | 10 | 20 | 20 | ||||
A sum 降采样 |
NaN | NaN | NaN | 15 | NaN | 5 | NaN |
B sum 下采样 |
10 | NaN | 20 | NaN | NaN | NaN | 20 |
sum 汇总结果 |
10 | NaN | 20 | 15 | NaN | 5 | 20 |
如果我们请求的输出没有填充策略,则不会发出t0+20s
或t0+40s
的值或时间戳。另外,将对系列B
的t0+30s
和t0+50s
处的值进行线性插值,以填充要与系列A
相加的值。