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

导航至

本文最初发表于 The New Stack,并经许可在此处转载。

将时间序列数据塞入熟悉的 Postgres 或 MySQL 数据库似乎很诱人,但出于许多原因,这是一个坏主意。

对于新手或不熟悉的人来说,时间序列数据表现出与关系数据相似的特征,但这两种数据类型存在一些关键差异。关系数据的主要目标是维护世界当前状态的准确表示,包括其对象以及它们之间的关系。时间序列数据讲述了当前世界上正在发生的事情。

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

关系数据与时间序列数据

顾名思义,关系数据是说明关系的数据。关系数据的目的是维护对象及其彼此关系的准确记录。关系数据是事务性的,并且会频繁更新以保持准确性。

时间序列数据的目的是为分析和概括提供洞察力。序列是观测流,因此数据点本质上与来源相关,但数据点是不可变的,因为过去无法改变。虽然单个点可能没有用,但整个序列揭示了源随时间的变化。

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

这似乎是显而易见的,但关系数据库是为关系数据构建的。时间序列数据的特征和工作负载非常不同,因此关系数据库不适用于它们。

关系数据库无法处理大规模时间序列的摄取速度。由于这是一个与规模相关的问题,因此只有在规模化时才会出现。因此,很多人开始使用关系数据库处理时间序列,但一旦达到扩展拐点,最终不得不做更多的工作。

对于存储在关系数据库中的每个原始来源,估计需要 10 倍以上的存储空间来存储其相关的时间序列数据。关系数据库不是为这种类型的增长曲线构建的,关系数据库的功能也不是这种类型的数据所需要的。

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

关系数据库的另一个挑战是由于显式模式要求而缺乏灵活性。每当您需要更新模式时,数据库都必须进行劳动密集型的迁移。这是一项冒险的任务,因为无论开发人员在过程中多么小心,都可能丢失或损坏数据。

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

InfluxDB 是一个专门构建的时间序列数据库,通过云、本地部署和开源交付。它旨在满足时间序列数据的需求。在扩展方面,在 InfluxData 的内部基准测试中,InfluxDB 每秒摄取的数据量比其他数据库高出几个数量级,而使用的 CPU 和内存明显更少,即使是那些声称已针对时间序列进行优化的数据库也是如此。

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 用户来说更易于访问。

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