TimescaleDB核心概念(上)(翻译整理)

2022-03-25 00:00:00 数据 分布式 节点 时间 分区

内容概览

  1. 超表和块

  2. 扩展 TimescaleDB

  3. 分布式超表

  4. 压缩


超表和块

超表

从用户的角度来看,TimescaleDB 公开了看起来像单个表的东西,称为hypertables。超表是与数据交互的主要点,因为它提供了可以通过标准 SQL 查询的标准表抽象。在 TimescaleDB 中创建超表需要两个 SQL 命令:(CREATE TABLE使用标准 SQL 语法),然后是SELECT create_hypertable().


几乎所有与 TimescaleDB 的用户交互都使用超表。插入、更新或删除数据、通过 SELECT 查询数据、更改表、添加新列或索引、与其他表或超表连接等等都可以(并且应该)在超表上执行。


但是,超表实际上是许多实际存储数据的单个表的抽象或虚拟视图,称为块。


超表和块

使用块在超表中分区

通过将超表的数据划分为一个(或潜在的多个)维度来创建块。所有超表都由属于时间列的值进行分区,时间列可能是时间戳、日期或各种整数形式。例如,如果时间分区间隔为一天,则时间戳属于同一天的行位于同一块内,而属于不同天的行属于不同的块。


TimescaleDB 在将行插入数据库时自动创建这些块。如果新插入行的时间戳属于数据库中尚不存在的日期,TimescaleDB 将创建一个与该日期对应的新块作为 INSERT 过程的一部分。否则,TimescaleDB 确定新行所属的现有块,并将行插入相应的块中。超表的分区间隔也可以随时间而改变(例如,为了适应不断变化的工作负载条件,因此在一个示例中,超表初可以每天创建一个新块,然后随着工作负载的增加每 6 小时更改为一个块)。


超表也可以按附加列进行分区——例如设备标识符、服务器或容器 ID、用户或客户 ID、位置、股票代码等。这种附加列上的分区通常使用散列(将所有设备或服务器映射到特定数量的散列桶中),尽管此处也可以使用基于间隔的分区。我们有时将按时间和这个附加维度分区的超表称为“时间和空间”分区。


这种时空分区主要用于分布式超表。通过这样的二维分区,每个时间间隔也被分区到包括分布式超表的多个节点上。在这种情况下,在同一小时内,有关设备某些部分的信息存储在每个节点上。这允许多节点 TimescaleDB 在该时间间隔内并行插入和查询数据。


每个块都使用标准数据库表实现。(在 PostgreSQL 内部,块实际上是“父”超表的“子表”。)块包括指定和强制执行其分区范围的约束,例如,块的时间间隔覆盖 ['2020-07- 01 00:00:00+00', '2020-07-02 00:00:00+00'),并且块中包含的所有行都必须具有该范围内的时间值。任何空间分区也反映为块约束。由于这些范围和分区不重叠,因此超表中的所有块在其分区维度空间中都是不相交的。


块约束的知识在内部数据库操作中被大量使用。插入超表的行会根据块的尺寸“路由”到正确的块。并且对超表的查询使用这些块的约束知识来仅将查询“下推”到适当的块:time > now() - interval '1 week'例如,如果查询指定,则数据库仅针对过去一周的块执行查询,并排除任何在那之前的大块。然而,这对用户来说是透明的,用户只需使用标准 SQL 语句查询超表。


Hypertables 和块的好处

这种基于块的架构有益于时间序列数据管理的许多方面。其中包括:


内存数据。可以配置块(基于它们的时间间隔),以便近的块(及其索引)适合内存。这有助于确保对近时间间隔的插入以及对近数据的查询通常访问已存储在内存中的数据,而不是从磁盘访问。但是 TimescaleDB 并不要求块只适合内存(否则会出错);相反,数据库遵循磁盘页面上的 LRU 缓存规则来维护内存数据和索引缓存。


本地索引。索引是独立构建在每个块上的,而不是跨所有数据的全局索引。这同样确保了来自新块的数据和索引通常都驻留在内存中,以便在插入数据时更新索引保持快速。并且 TimescaleDB 仍然可以确保包含任何分区键的键的全局性,考虑到其块的不相交性质,即给定一个的 (device_id, timestamp) 主键,首先识别给定约束的相应块,然后使用该块中的一个索引以确保性。但这仍然很容易与 TimecaleDB 的超表抽象一起使用:用户只需在超表上创建一个索引,这些操作(和配置)就会被推送到现有的和新的块中。


易于数据保留。在许多时间序列应用程序中,用户通常只想将原始数据保留一段时间,通常是出于成本、存储、合规性或其他原因。使用 TimescaleDB,用户可以根据时间范围快速删除数据块(例如,所有数据的时间戳超过 6 个月的数据块)。更简单的是,用户可以在 TimescaleDB 中创建数据保留策略以使其自动化,该策略使用其内部作业调度框架。基于块的删除速度很快——它只是从磁盘中删除一个文件——而不是删除单个行,这需要更昂贵的“真空”操作来稍后对这些删除的行进行垃圾收集和碎片整理。


基于年龄的压缩、数据重新排序等. 许多其他数据管理功能也可以利用这种基于块的架构,它允许用户对块执行特定命令或使用超表策略来自动化这些操作。其中包括 TimescaleDB 的本机压缩,它将块从传统的行主要形式转换为本质上更列式的布局,同时对每列采用特定于类型的压缩。或数据重新排序,它将存储在磁盘上的数据从插入的顺序异步重写为用户根据指定索引指定的顺序。例如,通过基于 (device_id, timestamp) 对数据进行重新排序,与特定设备关联的所有数据都将连续写入磁盘,从而可以更快地对特定设备的数据进行“深度和狭窄”扫描。


即时多节点弹性。TimescaleDB 支持跨多个节点的水平扩展。与传统的一维数据库分片(在扩展集群过程中必须将分片迁移到新添加的服务器)不同,TimescaleDB 支持弹性添加(或删除)新服务器,而无需任何立即重新平衡。添加新服务器时,现有块可以保留在其当前位置,而为未来时间间隔创建的块在新的服务器集上进行分区。然后 TimescaleDB 计划器可以处理这些重新配置中的查询,始终知道哪些节点正在存储哪些块。随后可以通过异步迁移块或根据需要通过数据保留策略处理服务器负载。


数据复制。可以通过在分布式超表上配置复制因子(在插入时作为 2PC 事务的一部分发生)或通过将较旧的块从一个节点复制到另一个节点以增加其复制因子,以事务方式在节点之间单独复制块,例如,在节点故障后(即将推出)。


数据迁移。块可以事务性地单独迁移。这种迁移可以跨越驻留在单个服务器上的表空间(磁盘),通常作为数据分层的一种形式;例如,将旧数据从更快、更昂贵的磁盘移动到更慢、更便宜的存储。这种迁移也可以发生在分布式超表中的节点之间,例如,为了在添加服务器后异步重新平衡集群或准备停用服务器(即将推出)。


扩展 TimescaleDB

TimescaleDB 支持三种主要部署选项:作为单个数据库服务器,在传统的主/副本部署中,或在具有水平可扩展性的多节点部署中。


单实例(节点)

安装了 TimescaleDB 的单个 PostgreSQL 实例通常可以支持非常大的数据集和应用程序查询的需求。在没有 TimescaleDB 的常规 PostgreSQL 实例中,在单台机器上扩展数据库性能的一个常见问题是内存和磁盘之间的重大成本/性能权衡。终,整个数据集无法放入内存,您需要将数据和索引写入磁盘。


一旦数据足够大以至于我们无法将索引的所有页面(例如,B 树)放入内存中,那么更新树的随机部分可能涉及从磁盘交换数据。像 PostgreSQL 这样的数据库为每个表索引保留一个 B 树(或其他数据结构),以便有效地找到该索引中的值。因此,随着您索引更多列,问题变得更加复杂。


但是因为 TimescaleDB 创建的每个块本身都存储为单独的数据库表,所以它的所有索引都只在这些小得多的表中构建,而不是代表整个数据集的单个表。因此,如果我们适当地调整这些块的大小,我们可以将新的表(及其 B 树)完全放入内存中,并避免这种交换到磁盘的问题,同时保持对多个索引的支持。


主复制和备份复制

TimescaleDB 支持使用标准 PostgreSQL 物理复制协议从“主”数据库服务器到单独的“副本”服务器的流式复制。该协议通过将数据库修改记录从主服务器流式传输到一个或多个副本来工作,然后可以将其用作只读节点(以扩展查询)或用作故障转移服务器(以实现高可用性)。


PostgreSQL 流复制利用了预写日志 (WAL),这是一个仅附加的指令系列,可捕获每个原子数据库更改。复制通过不断地将 WAL 的段从主服务器传送到任何连接的副本来工作。然后每个副本应用 WAL 更改并使其可用于查询,确保对主节点的操作以原子方式应用,并且以相同的顺序应用于每个副本。


TimescaleDB(来自底层 PostgreSQL 功能)支持各种物理复制选项,以权衡性能和一致性。


复制可以同步发生。当在主节点上执行插入或模式修改操作时,该操作会在主节点返回任何结果之前复制(甚至应用)到副本。这可确保副本始终保持新状态。


复制也可以异步发生。对主节点的操作在执行后立即返回给客户端,但任何更改都会排队等待异步传输到任何副本。异步副本通常用于临时数据探索,以避免副本上的繁重查询负载干扰生产主服务器。


实际上,单个 TimescaleDB 主数据库可以同时具有同步和异步副本,以实现 HA 故障转移和读取扩展的混合。主/备份复制的主要限制是每台服务器都存储数据库的完整副本 。


多节点 TimescaleDB 和分布式超表

TimescaleDB 2.0 还支持跨多个服务器的水平扩展。分布式超表可以分布在多个节点上,而不是存储数据的完整副本的主节点(和每个副本) ,这样每个节点只存储分布式超表的一部分(即块的子集) . 这允许 TimescaleDB 扩展存储、插入和查询,超出单个 TimescaleDB 实例的能力。分布式超表和常规超表看起来非常相似,主要区别在于分布式块不存储在本地(以及其他一些当前限制)。


在 TimescaleDB 的多节点部署中,数据库可以充当访问节点或数据节点的角色;两者都运行相同的 TimescaleDB 软件以简化操作。


客户端连接到访问节点数据库。客户端可以在访问节点上创建一个分布式超表,它存储有关不同数据节点的集群范围信息以及属于分布式超表的块如何分布在这些数据节点上。访问节点还可以存储非分布式超表,以及常规 PostgreSQL 表。


数据节点不存储集群范围的信息,否则看起来就好像它们是独立的 TimescaleDB 实例。


客户端通过访问节点与分布式超表交互,执行模式操作、插入数据或查询数据,就好像它是一个标准表一样。当接收到查询时,访问节点使用关于块的本地信息来确定将查询下推到哪些数据节点。跨集群的查询优化试图小化数据节点和访问节点之间传输的数据,以便尽可能在数据节点上执行聚合,并且仅将聚合或过滤的结果传递回访问节点以进行合并并返回给客户端。



分布式超表

TimescaleDB 通过利用与上述相同的超表和块原语,支持跨多个节点(即集群)分布超表。这允许 TimescaleDB 扩展插入和查询超出单个 TimescaleDB 实例的功能。


分布式超表和常规超表看起来非常相似,主要区别在于分布式块不存储在本地。还有一些分布式超表不支持的常规超表特性。


分布式数据库和节点

分布式超表存在于分布式数据库中,该数据库由存储在一个或多个 TimescaleDB 实例中的多个数据库组成。作为分布式数据库一部分的数据库可以承担访问节点或数据节点的角色(但不能同时充当两者)。


客户端连接到访问节点数据库。然后访问节点将请求和查询适当地分发到数据节点,并聚合从数据节点接收到的结果。访问节点存储有关不同数据节点的集群范围信息以及块在这些数据节点之间的分布方式。访问节点还可以存储非分布式超表,以及常规 PostgreSQL 表。


数据节点不存储集群范围的信息,否则看起来就好像它们是独立的 TimescaleDB 实例。您不应直接访问数据节点上的超表或块。这样做可能会导致不一致的分布式超表。


需要注意的是,访问节点和数据节点都运行 TimescaleDB,并且出于所有意图和目的,从操作的角度来看,它们就像 TimescaleDB 的单个实例一样。


分布式数据库和节点

分布式超表存在于分布式数据库中,该数据库由存储在一个或多个 TimescaleDB 实例中的多个数据库组成。作为分布式数据库一部分的数据库可以承担访问节点或数据节点的角色(但不能同时充当两者)。


客户端连接到访问节点数据库。然后访问节点将请求和查询适当地分发到数据节点,并聚合从数据节点接收到的结果。访问节点存储有关不同数据节点的集群范围信息以及块在这些数据节点之间的分布方式。访问节点还可以存储非分布式超表,以及常规 PostgreSQL 表。


数据节点不存储集群范围的信息,否则看起来就好像它们是独立的 TimescaleDB 实例。您不应直接访问数据节点上的超表或块。这样做可能会导致不一致的分布式超表。


需要注意的是,访问节点和数据节点都运行 TimescaleDB,并且出于所有意图和目的,从操作的角度来看,它们就像 TimescaleDB 的单个实例一样。


配置分布式超表


为确保佳性能,您应该按时间和空间对分布式超表进行分区。如果仅按时间对数据进行分区,则该块必须在访问节点选择另一个数据节点来存储下一个块之前填满,因此在该块的时间间隔内,对新间隔的所有写入都由单个数据节点处理,而不是而不是在所有可用数据节点之间进行负载平衡。另一方面,如果您指定空间分区,则访问节点会根据空间分区将块分布在多个数据节点上,以便为给定的块时间间隔创建多个块,并且对该近时间间隔的读取和写入都是跨集群负载均衡。


默认情况下,如果未指定值,我们会自动将空间分区数设置为等于数据节点数。如有必要,系统还会在添加新数据节点时增加空间分区的数量。如果手动设置,我们建议空间分区的数量等于或倍数与分布式超表关联的数据节点的数量,以实现跨数据节点的佳数据分布。在多个空间分区的情况下,只有个空间分区用于确定块如何跨服务器分布。


扩展分布式超表


随着时间序列数据的增长,一个常见的用例是添加数据节点以扩展分布式超表的存储和计算能力。因此,TimescaleDB 可以通过简单地将数据节点添加到分布式数据库来进行弹性扩展。

如前所述,TimescaleDB 会随着新数据节点的添加而调整空间分区的数量。尽管现有块没有更新其空间分区,但新设置将应用于新创建的块。由于这种行为,当集群大小增加时,我们不需要在数据节点之间移动数据,只需更新下一个时间间隔的数据分布方式。对新传入数据的写入利用了新的分区设置,而访问节点仍然可以支持跨所有块的查询(即使是使用旧分区设置创建的那些)。请注意,虽然空间分区的数量可以更改,但不能更改数据分区所在的列。


压缩

本机压缩

TimescaleDB 支持本地压缩存储在超表中的数据的能力。本机压缩不需要使用任何特定的文件系统或外部软件。压缩时间序列数据可以显着降低数据的存储需求,并且在许多情况下,可以加快对历史压缩数据的查询的响应速度。


压缩由 TimescaleDB 的内置作业调度程序框架提供支持。我们利用它来将单个块从未压缩的基于行的形式异步转换为跨超表的压缩列形式:一旦块足够老,块就会以事务方式从行转换为列形式。


使用本机压缩,即使 TimescaleDB 中的单个超表以行和列形式存储数据,用户也无需担心这一点:他们在查询数据时继续看到标准的基于行的模式。这类似于在解压缩的列数据上构建视图。


TimescaleDB 通过 (1) 透明地附加以标准行格式存储的数据以及来自列格式的解压缩数据,以及 (2) 在查询时透明地从选定行中解压缩单个列,从而实现了此功能。


在查询期间,正常处理未压缩的块,而来自压缩块的数据首先在查询时解压缩并转换为标准行格式,然后再附加或合并到其他数据中。这种方法与您对 TimescaleDB 的所有期望兼容,例如关系 JOIN 和分析查询,以及积极的约束排除以避免处理块。


为什么使用 TimescaleDB?

TimescaleDB 是时间序列数据的关系数据库。


它是作为 PostgreSQL 的扩展实现的,这意味着它作为同一进程的一部分在 PostgreSQL 服务器中运行,其代码引入了时间序列数据管理的新功能、数据分析的新功能、新的查询计划器和查询执行优化和新的存储机制,以实现更具成本效益和性能的分析。对包含 TimescaleDB 的 PostgreSQL 数据库的任何操作(无论是 SELECT 还是 INSERT,或创建索引等模式管理)首先由 TimescaleDB 处理,以确定应如何针对 TimescaleDB 的数据结构计划或执行它们。


这种扩展模型允许数据库利用 PostgreSQL 的丰富性,从 40 多种数据类型(整数、浮点数、字符串、时间戳、数组和 JSON 数据类型)到十几种类型的索引、复杂的模式、查询规划器,以及与 TimescaleDB 完美配合的更大扩展生态系统(包括通过 PostGIS 提供的地理空间支持、使用 pg_stat_statements 进行监控、外部数据包装器等)。


这种设计还允许 TimescaleDB 从可靠性、健壮性、安全性和生态系统的角度利用 PostgreSQL 的成熟度。可以使用 PostgreSQL 的物理复制创建多个副本以获得更高的可用性和扩展读取查询;用于连续备份的快照和增量 WAL 流,以支持完整的时间点恢复;架构、表甚至行级别的基于角色的访问控制;并与大量使用标准 PostgreSQL 协议的第三方连接器和系统集成,例如流行的编程语言、ORM、数据科学工具、流系统、ETL 工具、可视化库和仪表板等。


同时,TimescaleDB 通过在 PostgreSQL 的查询计划器、数据和存储模型以及执行引擎中添加挂钩,充分利用了可用于扩展的高度自定义。这允许专门为时间序列数据设计的新的功能,包括:


透明和自动化的时间分区,时间序列表自动连续地“分块”成更小的间隔,以提高性能并解锁各种数据管理功能。新块的数据和索引自然保留在内存中,确保对新数据的快速插入和高性能查询。


具有数据类型特定压缩的本机列压缩,根据数据是时间戳、整数、浮点数、字符串还是其他数据采用各种的算法。用户通常报告 94-97% 的存储减少和对压缩数据的更快查询。


连续和实时聚合,其中数据库持续和增量地维护聚合时间序列数据的物化视图以提高查询性能,同时正确处理延迟数据或数据回填。TimescaleDB 甚至使查询能够透明地将预先计算的聚合与新的原始数据合并,以确保始终获得新的答案。


自动化时间序列数据管理功能,例如显式或基于策略的数据保留策略、数据重新排序策略、聚合和压缩策略、下采样策略等。


数据库内作业调度框架,支持本地策略并支持用户定义的操作,包括用 SQL 或 PL/pgSQL 编写的操作。


水平可扩展的多节点操作,可跨多个 TimescaleDB 数据库自动且弹性地扩展您的时间序列数据,同时仍提供单个时间序列表的抽象。


为了更好地理解 TimescaleDB,我们首先要更好地解释TimescaleDB如何扩展的两个主要概念:它对超表 和块的数据抽象(以及如何存储和处理这些),以及如何将 TimescaleDB 部署为单节点,使用物理副本,或作为多节点集群启用分布式超表。

来源 https://mp.weixin.qq.com/s/aSfqO-SSpFMm_kw5ytq37g

相关文章