时序数据可能是独特的,因为它需要处理浅查询和宽查询,例如“过去 10 分钟内部署发生了什么”,以及深查询和窄查询,例如“过去 24 小时内此服务器的平均 CPU 使用率是多少”。时序数据通常也具有非常高的插入速率;每秒数十万次的写入对于时序数据集来说非常正常。此外,时序数据通常非常精细,并且数据以比许多其他数据集更高的分辨率收集。这可能会导致随着时间的推移收集 TB 级的数据。

所有这些都意味着,如果您需要出色的压缩率,您可能需要在开始摄取数据之前考虑数据库的设计。本节介绍在设计数据库以获得最大压缩效果时需要考虑的一些事项。

TimescaleDB 构建于 PostgreSQL 之上,PostgreSQL 本质上是一个面向行的数据库。由于时序数据是按时间顺序访问的,因此当您启用压缩时,TimescaleDB 会将许多宽数据行转换为单行数据,称为数组形式。这意味着新的宽行的每个字段都存储一个包含整个列的有序数据集。

例如,如果您有一个包含如下数据的表

时间戳设备 ID状态代码温度
12:00:01A070.11
12:00:01B069.70
12:00:02A070.12
12:00:02B069.69
12:00:03A070.14
12:00:03B469.70

您可以将其转换为数组形式的单行,如下所示

时间戳设备 ID状态代码温度
[12:00:01, 12:00:01, 12:00:02, 12:00:02, 12:00:03, 12:00:03][A, B, A, B, A, B][0, 0, 0, 0, 0, 4][70.11, 69.70, 70.12, 69.69, 70.14, 69.70]

即使在压缩任何数据之前,这种格式也可以通过减少每行开销来立即节省存储空间。PostgreSQL 通常每行添加少量字节的开销。因此,即使没有任何压缩,此示例中的模式在磁盘上也比以前的格式更小。

这种格式排列数据,使相似的数据(例如时间戳、设备 ID 或温度读数)连续存储。这意味着您可以随后使用特定于类型的压缩算法来进一步压缩数据,并且每个数组都是单独压缩的。有关所用压缩方法的更多信息,请参阅压缩方法部分

当数据为数组格式时,您可以非常快速地执行需要列子集的查询。例如,如果您有一个像这样的查询,它要求过去一天的平均温度

SELECT time_bucket(1 minute, timestamp) as minute
AVG(temperature)
FROM table
WHERE timestamp > now() - interval1 day
ORDER BY minute DESC
GROUP BY minute;

查询引擎可以仅获取和解压缩时间戳和温度列,以有效地计算并返回这些结果。

最后,TimescaleDB 使用非内联磁盘页来存储压缩数组。这意味着行内数据指向存储压缩数组的辅助磁盘页,并且主表中的实际行变得非常小,因为它现在只是指向数据的指针。当查询像这样存储的数据时,仅从磁盘读取所需列的压缩数组,从而通过减少磁盘读取和写入来进一步提高性能。

在前面的示例中,数据库无法知道需要获取和解压缩哪些行才能解析查询。例如,数据库无法轻易确定哪些行包含过去一天的数据,因为时间戳本身位于压缩列中。您不希望必须解压缩数据块甚至整个 hypertable 中的所有数据,才能确定需要哪些行。

TimescaleDB 自动在行中包含更多信息,并包含额外的分组以提高查询性能。当您手动或通过压缩策略压缩 hypertable 时,指定 ORDER BY 列会有所帮助。

ORDER BY 列指定压缩批次中的行如何排序。对于大多数时序工作负载,这是按时间戳排序的,因此如果您未指定 ORDER BY 列,TimescaleDB 默认使用时间列。您还可以指定其他维度,例如位置。

对于每个 ORDER BY 列,TimescaleDB 自动创建额外的列,用于存储该列的最小值和最大值。这样,查询计划器可以查看压缩列中时间戳的范围,而无需进行任何解压缩,并确定该行是否可能与查询匹配。

当您压缩 hypertable 时,您还可以选择指定 SEGMENT BY 列。这允许您按特定列对压缩行进行分段,以便每个压缩行对应于有关单个项目的数据,例如,特定的设备 ID。这进一步允许查询计划器确定该行是否可能与查询匹配,而无需首先解压缩列。例如

设备 ID时间戳状态代码温度最小时间戳最大时间戳
A[12:00:01, 12:00:02, 12:00:03][0, 0, 0][70.11, 70.12, 70.14]12:00:0112:00:03
B[12:00:01, 12:00:02, 12:00:03][0, 0, 4][69.70, 69.69, 69.70]12:00:0112:00:03

通过这种方式分段数据,对设备 A 在时间间隔之间的查询变得非常快。查询计划器可以使用索引来查找设备 A 的那些行,这些行包含至少一些与指定间隔对应的时间戳,即使是顺序扫描也相当快,因为评估设备 ID 或时间戳不需要解压缩。这意味着查询执行器仅解压缩与那些选定行对应的时间戳和温度列。

关键词

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