不要让时间序列数据破坏您的关系型数据库

导航到

本文最初发表在 The New Stack 上,并在此处获得许可转载。

将时间序列数据塞入熟悉的关系型数据库(如Postgres或MySQL)中,看似诱人,但实际上有很多原因都不建议这样做。

对于初学者或不太熟悉的人来说,时间序列数据与关系型数据具有相似的特征,但两种数据类型存在一些关键差异。关系型数据的主要目标是维护对象及其之间关系的准确表示。时间序列数据讲述的是当前世界中正在发生的事情。

例如,考虑 DevOps 工程师需要的实时洞察和即时的信号/异常检测。您可以使用持续的观察流来检测模式、查找相关信息、识别和去除噪声,并揭示预示安全威胁的意外模式。时间序列数据使这些洞察成为可能。当然,时间序列数据可以适应行/表格式,但它更适合具有时间戳作为主键的列式数据库。

关系型数据与时间序列数据

正如其名所示,关系型数据是用来展示关系的。关系型数据的目的在于维护对象及其相互关系的准确记录。关系型数据是事务性的,并频繁更新以保持准确性。

时间序列数据的目的在于提供分析和总结的洞察。一个系列是一系列的观察结果,因此从本质上讲,数据点是按照来源相关联的,但由于过去无法改变,因此数据点是不可变的。虽然单个点可能没有用,但整个系列揭示了来源随时间的变化。

关系数据库是为关系型数据构建的

这看起来可能很明显,但关系数据库是为关系型数据构建的。时间序列数据的特点和工作负载与之非常不同,因此关系数据库不适合处理它们。

关系数据库无法处理时间序列数据的大规模摄入速度。由于这是一个与规模相关的问题,它仅在达到扩展拐点时才会显现出来。因此,很多人开始使用关系数据库来处理时间序列数据,但当他们达到扩展拐点时,不得不做更多的工作。

对于存储在关系型数据库中的每个源数据,其关联的时间序列数据需要的存储空间大约是其10倍。关系型数据库并非为这种增长模式而构建,其特性也不适用于此类数据。

一个例子是,时间序列数据更倾向于在读写和数据库备份之间保持较低的延迟。当关系型数据库的工作负载达到可扩展性的临界点时,由于作为安全预防措施而进行数据库备份,写入速度会减慢。较高的延迟会阻碍自动化系统立即对任何异常情况做出反应的能力。

关系型数据库的另一个挑战是,由于明确的模式要求,它们缺乏灵活性。每次需要更新模式时,数据库都必须进行劳动密集型的迁移。这是一个风险较高的任务,因为无论开发者在这个过程中多么小心,都可能导致数据丢失或损坏。

时间序列数据库是为时间序列数据构建的

InfluxDB是一款专门为时间序列数据构建的数据库,可通过云、本地和开源方式提供。它旨在满足时间序列数据的需求。在可扩展性方面,在InfluxData的内部基准测试中,InfluxDB每秒处理的请求数量比其他数据库大得多,即使是那些声称针对时间序列进行优化的数据库。

InfluxDB采用“写入时模式”,这意味着开发者可以通过简单地将新维度和字段添加到他们的写入操作中来添加它们。无需对任何生产或开发数据库进行更改要求。这为具有变化数据形状的工作负载提供了灵活性。

Apache Arrow用于时间序列

时间序列数据的关键是理解世界的当前状况,并提供即时的见解和行动。关系型数据库可以执行基本的数据操作,但不能在多个观测值上执行高级计算和分析。

由于时间序列数据工作负载非常大,它们需要一个可以轻松处理大型数据集的数据库。Apache Arrow专门设计用于移动大量列式数据。在Arrow上构建数据库为开发者提供了更多的选项,通过高级数据分析以及机器学习和人工智能工具(如Pandas)的实施,有效地操作他们的数据。

有些人可能会倾向于简单地使用Arrow作为当前解决方案的外部工具。然而,这种方法不可行,因为如果数据库不直接以Arrow格式返回数据,生产应用程序将难以确保有足够的内存来处理大型数据集。代码源也将缺少Arrow提供的压缩。将未压缩的字节传输到网络上会增加数据库和代码之间的延迟,从而影响整体性能。

缩短学习曲线

在Apache生态系统中构建InfluxDB为将SQL支持添加到时间序列数据库中创造了机会。InfluxDB使用DataFusion作为其查询引擎,而DataFusion使用SQL作为查询语言,这意味着现在任何了解SQL的人都可以查询时间序列。无需额外的语言要求。

为了进一步增强访问的便利性,DataFusion中已经实现了三个特定于时间序列的功能。这些都是开源的,因此Apache Arrow社区中的任何人都可以从中受益或为其做出贡献。

1·  date_bin()  –  Creates rows that are time windows of data with an aggregate.
2·  selector_first(),  selector_last()  –  Provide the first or last row of  a  table that meet specific criteria.
3·  time_bucket_gapfill()  –  Returns windowed data,  and if there are windows that lack data it will fill those gaps.

结论

时间序列数据与关系数据具有不同的特性、存储需求和负载。由于数据类型看起来相似,因此了解这些差异非常重要。在生产过程中越晚发现这些问题,解决起来就越困难。

时间序列数据与InfluxDB等时间序列数据库配合使用最佳,这可以应对高吞吐量时的低延迟,以及写入时数据收集的灵活性以及高级数据分析。InfluxDB的本地SQL支持使SQL用户能够更容易地访问时间序列数据工作负载。

通过简单地添加时间序列数据库到您的技术栈,您可以避免或修复上述任何陷阱。