再过30分钟你就能了解TimescaleDB中的连续聚合啦

583 阅读6分钟

1. 概念

聚合是一段时间内原始数据的汇总。

考虑到需要处理大量数据以计算和重新计算一段时间内的聚合,计算时间序列数据的聚合可能是计算密集型的。此外,在摄取数据的同时计算聚合可能会导致摄取速率下降,因为计算资源在两个资源密集型进程之间分配。连续聚合解决了这两个问题。

连续聚合是自动刷新的物化视图,因此它们极大地加快了需要处理大量数据的工作负载。与其他数据库不同,视图会在添加新数据或根据计划修改旧数据时在后台自动刷新。

  • 连续聚合在后台自动预先计算和维护来自指定查询的结果,并允许像检索任何其他数据一样检索结果。
  • 添加新数据或根据计划修改旧数据时,视图会在后台自动刷新。

对于可能熟悉视图和物化视图的 PostgreSQL 用户,以下是连续聚合的不同之处:

  • 与 PostgreSQL 视图不同,连续聚合在查询时不会执行计算。
  • 与物化视图不同,它不需要手动刷新,因为它可以根据计划进行刷新。

连续聚合加快了仪表板和可视化的速度,汇总了高频采样的数据并查询长时间内的下采样数据。

2. 创建

首先定义视图。然后,创建一个策略来安排连续聚合的刷新。

2.1 定义视图

示例:这是定义要在连续聚合中维护的查询的 SQL 语句。它计算所有天气指标的每日平均值,以及高和低温度。

-- Continuous aggregates
-- Define view
CREATE MATERIALIZED VIEW weather_metrics_daily WITH ( timescaledb.continuous ) AS SELECT
time_bucket ( '1 day', TIME ) AS bucket,
city_name,
AVG ( temp_c ) AS avg_temp,
AVG ( feels_like_c ) AS feels_like_temp,
MAX ( temp_c ) AS max_temp,
MIN ( temp_c ) AS min_temp,
AVG ( pressure_hpa ) AS pressure,
AVG ( humidity_percent ) AS humidity_percent,
AVG ( rain_3h_mm ) AS rain_3h,
AVG ( snow_3h_mm ) AS snow_3h,
AVG ( wind_speed_ms ) AS wind_speed,
AVG ( clouds_percent ) AS clouds 
FROM
	weather_metrics 
GROUP BY
	bucket,
	city_name WITH NO DATA;

2.2 填充

创建了连续聚合,但它没有具体化任何数据。有两种填充连续聚合的方法:通过手动刷新或自动化策略。这些方法能够在方便的时候刷新连续聚合中的具体数据(例如,在数据库的低查询加载期间)。

2.2.1 手动刷新

使用“一次性刷新”手动刷新连续聚合。这对于仅刷新过去特定时间段的数据或如果想一次性实现大量数据非常有用。 示例:刷新weather_metrics_daily从 2010 年 1 月 1 日开始到 2021 年 1 月 1 日结束的时间段的连续聚合:

-- manual refresh-- refresh data between 1 Jan 2010 and 2021CALL 
refresh_continuous_aggregate('weather_metrics_daily','2010-01-01', '2021-01-01');

查询我们对 2009 年 1 月 1 日之前的数据的连续聚合表明它确实填充了上述时间范围内的数据,因为返回的行是 2010 年 1 月 1 日的数据:

-- Show that manual refresh worked
SELECT * FROM weather_metrics_dailyWHERE bucket > '2009-01-01'ORDER BY bucket ASC;

2.2.2 自动刷新

创建一个每两周自动更新连续聚合的策略

-- create policy-- refresh the last 6 months of data every 2 weeks

SELECT
	add_continuous_aggregate_policy ( 'weather_metrics_daily', start_offset => INTERVAL '6 months', end_offset => INTERVAL '1 hour',   schedule_interval  =>  INTERVAL  '14 days' )

上述策略每 14 天运行一次 ( schedule_interval)。当它运行时,它会根据定义连续聚合的查询,具体化执行时间的6 个月 ( start_offset) 到 1 小时 ( ) 之间的数据。end_offset``weather_metrics_daily

自动化策略对于需要返回近时间范围内的数据的连续聚合很有用,因为它们可以帮助它们保持新状态。

3. 查询

连续聚合实际上是一种特殊的超表,因此可以像查询常规超表一样查询、查看和修改它们的块。还可以在连续聚合超表上添加数据保留策略和删除块。限制是不能再对这些连续聚合应用压缩或连续聚合。

查询连续聚合时,系统会读取并处理小得多的物化表,该表已按预定时间间隔刷新。这使得查询连续聚合对于加速仪表板、汇总高频采样的数据以及长时间查询下采样的数据非常有用。

此外,查询连续聚合不会减慢INSERT操作速度,因为数据被插入到与连续聚合底层不同的超表中。

一个查询示例:它在连续聚合 ( weather_metrics_daily) 上的性能要优于在超表 ( weather_metrics) 上的性能。这是一个查询,查看过去 6 年纽约的气温如何变化。它返回 2015 年至 2021 年间纽约市的时间以及每日高、低和平均气温:

-- Continuous aggregate query example
-- Temperature in New York 2015-2021
SELECT
	bucket,
	max_temp,
	avg_temp,
	min_temp 
FROM
	weather_metrics_daily 
WHERE
	bucket >= '2015-01-01' 
	AND bucket < '2021-01-01' 
	AND city_name LIKE'New York' 
ORDER BY
	bucket ASC;

由于相关时间段的数据已填充到连续聚合中并按天聚合,因此此类查询执行速度很快。像这样的查询用于历史分析,通常用于绘制温度随时间变化的图表。

4. 实时聚合

默认情况下,连续聚合支持实时聚合,即在查询时将聚合数据和原始数据结合起来,以获得新的结果。(如果需要,可以将其关闭,但大多数开发人员默认希望此行为)。

关闭实时聚合后,连续聚合仅返回它们已物化(刷新)的时间段内的数据的结果。如果查询连续聚合以获取比上次具体化时间更新的数据,它不会返回它或返回过时的结果。

启用实时聚合后,始终会收到新的结果,因为查询连续聚合会返回已经物化的数据以及查询时可用的超表中的新原始数据。

实时聚合提供了两全其美的优势:连续聚合的性能和实时查询的新数据,而不会降低查询和从头开始聚合所有原始数据的性能。

例如,考虑这个查询的结果,它选择过去两年所有天气指标的每日聚合:

-- Real-time aggregation
SELECT
	* 
FROM
	weather_metrics_daily 
WHERE
	bucket > now( ) - 2 * INTERVAL '1 year' 
ORDER BY
	bucket DESC;

返回的行的时间值比 2021 年 1 月 1 日新,这是在连续聚合中具体化数据的结束日期(通过本教程前面的手动刷新完成)。尽管没有通过手动刷新或自动化策略实现新数据(因为上面创建的策略尚未运行),但由于实时聚合,仍然可以获得新数据。

这使得实时聚合非常适合许多近乎实时的监控和分析用例,特别是对于始终需要新数据的仪表板或报告。正是出于这个原因,我们建议保持设置打开。