Timescale 的分层存储架构包括标准高性能存储层和构建在 Amazon S3 上的低成本对象存储层。您可以将标准层用于需要快速访问的数据,并将对象层用于不常用的历史数据。来自单个超表的数据块(包括压缩数据块)可以跨越这两个存储层。压缩数据块在分层后使用不同的存储表示形式。

在高性能存储中,数据块以块格式存储。在对象存储中,它们以压缩的列式格式存储。为了在各种平台之间实现更好的互操作性,此格式与数据库内部格式不同。它允许在更长的时间段内进行更高效的列式扫描,并且 Timescale Cloud 使用其他元数据和查询优化来减少需要从对象存储层获取以满足查询的数据量。

无论您的数据存储在哪里,您仍然可以使用标准 SQL 查询它。单个 SQL 查询使用数据块排除算法透明地从适当的数据块中提取数据。您可以对分层数据执行 JOIN 操作、构建视图,甚至在其上定义连续聚合。事实上,由于连续聚合的实现也使用超表,因此它们也可以分层到低成本存储。

对象存储层不仅仅是一个归档解决方案。它也是

  • 经济高效:以更低的成本存储大量数据。您只需为存储的内容付费,查询无需额外付费。

  • 可扩展:突破可以直接附加到 Timescale 服务的存储(目前为 16 TB)的限制。

  • 在线:您的数据始终存在,并且可以在需要时进行查询

分层存储后端的工作原理是定期和异步地将旧数据块从高性能存储移动到对象存储。在那里,它以 Apache Parquet 格式存储,这是一种压缩的列式格式,非常适合 S3。在 Parquet 文件中,一组行被分组在一起形成一个行组。在一个行组中,多行中单列的值存储在一起。

默认情况下,从 Timescale 服务查询时,不包括分层数据。但是,您可以通过为查询、会话甚至所有会话启用分层读取来访问分层数据。在启用分层读取后,当您运行常规 SQL 查询时,后台进程会透明地从数据所在的任何位置提取数据:标准高性能存储层、对象存储层或两者兼而有之。

各种 SQL 优化限制了需要从 S3 读取的内容

  • 数据块剪枝 - 排除查询时间窗口之外的数据块。
  • 行组剪枝 - 识别 Parquet 对象中满足查询的行组。
  • 列剪枝 - 仅获取查询请求的列。

结果是在高性能存储和对象存储之间进行透明查询,因此您的查询获取的数据与以前相同。

以下查询是针对分层数据集的,并说明了优化

EXPLAIN ANALYZE
SELECT count(*) FROM
( SELECT device_uuid, sensor_id FROM public.device_readings
WHERE observed_at > '2023-08-28 00:00+00' and observed_at < '2023-08-29 00:00+00'
GROUP BY device_uuid, sensor_id ) q;
QUERY PLAN
-------------------------------------------------------------------------------------------------
Aggregate (cost=7277226.78..7277226.79 rows=1 width=8) (actual time=234993.749..234993.750 rows=1 loops=1)
-> HashAggregate (cost=4929031.23..7177226.78 rows=8000000 width=68) (actual time=184256.546..234913.067 rows=1651523 loops=1)
Group Key: osm_chunk_1.device_uuid, osm_chunk_1.sensor_id
Planned Partitions: 128 Batches: 129 Memory Usage: 20497kB Disk Usage: 4429832kB
-> Foreign Scan on osm_chunk_1 (cost=0.00..0.00 rows=92509677 width=68) (actual time=345.890..128688.459 rows=92505457 loops=1)
Filter: ((observed_at > '2023-08-28 00:00:00+00'::timestamp with time zone) AND (observed_at < '2023-08-29 00:00:00+00'::timestamp with t
ime zone))
Rows Removed by Filter: 4220
Match tiered objects: 3
Row Groups:
_timescaledb_internal._hyper_1_42_chunk: 0-74
_timescaledb_internal._hyper_1_43_chunk: 0-29
_timescaledb_internal._hyper_1_44_chunk: 0-71
S3 requests: 177
S3 data: 224423195 bytes
Planning Time: 6.216 ms
Execution Time: 235372.223 ms
(16 rows)

EXPLAIN 说明了从对象存储层提取了哪些数据块

  1. 从对象存储层的数据块 42、43 和 44 中提取数据。
  2. 剪除行组,并将提取限制为 Parquet 对象中可能与查询过滤器匹配的偏移量的子集。仅提取 device_uuidsensor_idobserved_at 的数据,因为查询只需要这 3 列。
  • 有限的模式修改。 某些模式修改在具有分层数据块的超表上是不允许的。

    允许的修改包括:重命名超表、添加具有 NULL 默认值的列、添加索引、更改或重命名超表模式以及添加 CHECK 约束。对于 CHECK 约束,仅验证未分层的数据。也可以删除列,但您不能随后向分层超表添加与现在已删除的列同名的新列。

    不允许的修改包括:添加具有非 NULL 默认值的列、重命名列、更改列的数据类型以及向列添加 NOT NULL 约束。

  • 有限的数据更改。 您不能插入数据、更新或删除分层数据块。这些限制在数据块被安排分层后立即生效。

  • 非原生数据类型的低效查询计划器过滤。 查询计划器通过使用元数据来过滤掉不满足查询的列和行组,从而加速从我们的对象存储层读取数据。这适用于所有原生数据类型,但不适用于非原生类型,例如 JSONJSONBGIS

  • 延迟。 S3 的访问延迟高于本地存储。这可能会影响延迟敏感环境中的查询执行时间,尤其是较轻的查询。

  • 维度数量。 您不能将分层存储用于在多个维度上分区的超表。在启用分层存储之前,请确保您的超表仅按时间分区。

关键词

在此页面上发现问题?报告问题 或 在 GitHub 上编辑此页面