摘要:持续聚合是高性能的PostgreSQL物化视图,它可以提升性能,并为PostgreSQL中的时间序列数据启用实时分析。
持续聚合是高性能的PostgreSQL物化视图,它可以提升性能,并为PostgreSQL中的时间序列数据启用实时分析。
译自 Real-Time Analytics for Time Series: Continuous Aggregates,作者 Sarah Conway。
在寻找使用TimescaleDB的理由时,您通常会看到一个名为“连续聚合”的功能。这是一个强大的功能,当处理非常大或快速增长的数据集时,它可以帮助您大幅提高性能,使PostgreSQL能够轻松处理实时分析工作负载。让我们更详细地介绍一下。
连续聚合到底是什么?
简单来说,TimescaleDB中的连续聚合是超表的聚合查询的增量式自动更新的物化视图。
收集时间序列数据时,您的数据摄取频率通常远高于进一步分析或审计目的所需的频率。解析这些数据可能会出现问题,因为对极其大的数据集执行读写操作需要更长的时间。因此,创建了连续聚合。
与常规物化视图不同,连续聚合仅自动刷新新的或更改的数据,而不是重新计算整个视图。这会导致数据在后台预先聚合,从而加快源数据的查询和呈现速度。
这使得它们非常适合高效地实时查询大时间范围内的时序数据,因为聚合结果会在后台自动增量刷新,无需人工干预。
性能提升,存储减少
连续聚合通过性能测试实现了这些改进,性能测试显示查询运行时间的即时减少,并且可以使用DISTINCT、FILTER with HAVING以及其他查询子句(从Timescale 2.7开始)正常查询您的数据。需要解析的记录更少 = 更快的查询速度和更少的存储数据。它们也不依赖于原始源数据的存在。这意味着您可以删除底层的超表,同时仍然保留通过连续聚合下采样的数据集。仍然可以在此粒度较低的数据上执行历史分析或审计,同时为新记录腾出空间。
注意:每个连续聚合都可以有其自己的保留策略,以自动删除指定时间段后的一部分数据来自动实现此效果。
从Timescale 2.6开始,您可以应用TimescaleDB的原生列式压缩到连续聚合上,以进一步压缩磁盘空间。这甚至可以通过压缩策略来处理,在一定时间后自动压缩数据,并与数据保留策略结合,丢弃不再需要的旧数据集。
在现实世界中
用户报告说他们已成功将它们用于各种目的,包括:
实时可视化指标
对时间序列数据执行数据操作,例如传感器数据、历史股票信息或记录空气污染
对物联网设备设置的每日阈值进行强制执行
管理面向OLAP的数据库的数据
处理需要聚合的数百万(或更多)条现有记录
使用连续聚合
假设您需要在仪表板上显示传感器数据以分析结果。
SELECT time_bucket('1 hour', time) as hour, device_id, AVG(temperature) as avg_tempFROM sensor_dataWHERE time > NOW - INTERVAL '1 year'GROUP BY hour, device_idORDER BY hour DESC;当针对数百万行运行时,此类查询可能需要很长时间才能执行。更重要的是,每次执行此查询时,都必须每次运行时重新聚合——消耗不必要的资源并严重影响性能。
这就是连续聚合最有用之处;它们可以用来预先计算结果,形成一个自动更新的智能缓存。我们可以使用连续聚合重写上面的查询:
CREATE MATERIALIZED VIEW hourly_tempsWITH (timescaledb.continuous) ASSELECT time_bucket('1 hour', time) as hour, device_id, AVG(temperature) as avg_tempFROM sensor_dataGROUP BY hour, device_id;从那里,需要设置刷新策略来自动刷新连续聚合,以最佳方式满足您的用例。您可以出于历史目的保留已从源超表(手动或通过数据保留策略)中删除的连续聚合中的数据,并刷新所有其他数据;或者,您可以选择使连续聚合和超表自动保持同步,同时考虑这些保留策略。
SELECT add_continuous_aggregate_policy('hourly_temps', start_offset => INTERVAL '1 month', end_offset => INTERVAL '1 hour', schedule_interval => INTERVAL '1 hour');此查询在名为hourly_temps的连续聚合视图上设置刷新策略。此处,刷新窗口设置为仅查看当前时间之前最多一个月的数据(就像您使用数据保留策略单独删除一个月前较旧的原始数据一样,并希望保留连续聚合中的历史记录)。如果您更改此窗口之外的数据,则您的聚合将不会重新计算。
刷新窗口在当前时间之前结束一小时,以防止策略尝试刷新仍在写入大量数据的 数据(以及防止实时聚合出现问题,如果已启用)。
此策略每小时运行一次,以增量方式更新一个月到一小时窗口内的连续聚合。
注意:除了刷新策略之外,您还可以随时使用 refresh_continuous_aggregate 手动刷新连续聚合。现在,您会发现运行如下所示的查询会产生几乎即时的结果:
SELECT * FROM hourly_tempsWHERE hour > NOW - INTERVAL '1 year'ORDER BY hour DESC;旁注: 常被问到的一个问题是是否支持窗口函数。虽然答案是“不支持”,但有一个简单的解决办法:只需创建一个不包含窗口函数的连续聚合,然后在查询数据时对连续聚合使用窗口函数。
更多功能
从 TimescaleDB 2.9 开始,您甚至可以将连续聚合堆叠在连续聚合之上,从而实现分层连续聚合。为什么?因为你可以。(开玩笑。)为了节省存储成本,您可以在第一个连续聚合完成后删除用于计算初始连续聚合的原始原始数据。
可以基于辅助数据集计算其他聚合,就好像它们直接在原始原始数据集上执行一样。这有助于您立即获得性能优势,因为您是在数据集更小、数据点更少的情况下执行聚合,从而允许以更高的速度执行复杂的算法。
需要实时结果?这也是可能的——您可以启用实时聚合以在结果中显示最新的原始数据。(查看有关使用实时聚合的更多信息此处。您还可以查看性能测试.)的结果。
您可能会发现,值得研究一些额外的功能,这些功能可以高效地进行聚合操作,比如百分位数近似(uddsketch 和 percentile_agg)以及对变化数据集的数据分析(counter_agg 和 gauge_agg)。
从那里,还可以通过超函数扩展连续聚合的功能。超表支持这些功能,并为您提供高级功能,例如简化常用统计聚合的使用、使用计数器聚合函数收集数据以及使用心跳聚合监控系统运行状况。更多信息,请查看超函数文档。
来源:科学角落