TimescaleDB时序数据库初识

news/2024/5/17 9:48:02

注:本文翻译自https://legacy-docs.timescale.com/v1.7/introduction

TimescaleDB是一个开源时间序列数据库,针对快速摄取和复杂查询进行了优化。它说的是“完整的SQL”,因此像传统的关系数据库一样易于使用,并且以以前为NoSQL数据库保留的方式进行扩展。
与这两种选择(关系型与NoSQL)所需要的权衡相比,TimescaleDB为时间序列数据提供了两种方法的最佳选择:

易于使用

  • 完整的SQL接口,支持PostgreSQL本地支持的所有SQL(包括二级索引,非基于时间的聚合,子查询,join,窗口函数)。
  • 连接到任何使用PostgreSQL的客户端或工具,无需更改。
  • 面向时间的特性、API函数和优化。
  • 对数据保留策略的强大支持。

可伸缩性

  • 透明的时间/空间分区,支持向上扩展(单节点)和向外扩展(即将推出)。
  • 高数据写速率(包括批处理提交、内存索引、事务支持、数据回填支持)。
  • 在单个节点上适当大小的块(二维数据分区),以确保即使在大数据大小时也能快速摄取。
  • 跨块和服务器的并行操作。

可靠性

  • 从PostgreSQL设计而来,打包为extension。
  • 经过20多年PostgreSQL研究的可靠基础(包括流复制,备份)。
  • 灵活的管理选项(与现有PostgreSQL生态系统和工具兼容)。

什么是时间序列数据?

时间序列数据是总体上表示系统、流程或行为如何随时间变化的数据。
以时间为中心:数据记录总是有一个时间戳。
仅追加:数据几乎完全是仅追加的(insert)。
最近的:新数据通常是关于最近的时间间隔,我们很少更新或回填关于旧时间间隔的缺失数据。
然而,数据的频率或规律性并不那么重要;它可以每毫秒或每小时收集一次。它也可以定期或不定期收集(例如,当某些事件发生时,而不是在预定义的时间)。
与其他数据(如标准关系“业务”数据)相比,时间序列数据(以及支持它们的数据库)之间的一个关键区别是,对数据的更改是插入,而不是覆盖

时序数据应用场景

监控计算机系统:虚拟机、服务器、容器指标(CPU、空闲内存、网络/磁盘IOPs)、服务和应用程序指标(请求速率、请求延迟)。
金融交易系统:经典证券、新型加密货币、支付、交易事件。
物联网:来自工业机器和设备、可穿戴设备、车辆、物理容器、托盘、智能家居消费设备等传感器的数据。
事件应用:用户/客户交互数据,如点击流、页面浏览量、登录、注册等。
商业智能:跟踪关键指标和业务的整体健康状况。
环境监测:温度、湿度、压力、pH值、花粉计数、空气流量、一氧化碳(CO)、二氧化氮(NO2)、颗粒物(PM10)。

数据模型

作为一个支持完整SQL的关系数据库,TimescaleDB支持灵活的数据模型,可以针对不同的用例进行优化。这使得TimescaleDB与大多数其他时间序列数据库有些不同,后者通常使用“窄表”模型。
具体来说,TimescaleDB既支持宽表模型,也支持窄表模型。在这里,我们将使用一个物联网(IoT)示例讨论这两种模型的不同性能权衡和影响。
想象一下,一个由1000个物联网设备组成的分布式组,旨在以不同的间隔收集环境数据。这些数据可以包括:
Identifiers: device_id, timestamp
Metadata: location_id, dev_type, firmware_version, customer_id
Device metrics: cpu_1m_avg, free_mem, used_mem, net_rssi, net_loss, battery
Sensor metrics: temperature, humidity, pressure, CO, NO2, PM10
例如,您的传入数据可能看起来像这样:

timestampdevice_idcpu_1m_avgfree_memtemperaturelocation_iddev_type
2017-01-01 01:02:00abc12380500MB72335field
2017-01-01 01:02:23def45690400MB64335roof
2017-01-01 01:02:30ghi7891200MB5677roof
2017-01-01 01:03:12abc12380500MB72335field
2017-01-01 01:03:35def45695350MB64335roof
2017-01-01 01:03:42ghi789100100MB5677roof

现在,让我们看看对这些数据建模的各种方法。

窄表模型

大多数时间序列数据库将以下列方式表示这些数据:
将每个指标表示为一个单独的实体(例如,将cpu_1m_avg和free_mem表示为两个不同的东西)
为该指标存储一系列“时间”、“值”对
将元数据值表示为与该度量/标记集组合相关联的“标记集”
在此模型中,每个度量/标记集组合被认为是包含时间/值对序列的单个“时间序列”。
使用我们上面的例子,这种方法会产生9个不同的“时间序列”,每一个都由一组唯一的标签定义。

1. {name:  cpu_1m_avg,  device_id: abc123,  location_id: 335,  dev_type: field}
2. {name:  cpu_1m_avg,  device_id: def456,  location_id: 335,  dev_type: roof}
3. {name:  cpu_1m_avg,  device_id: ghi789,  location_id:  77,  dev_type: roof}
4. {name:    free_mem,  device_id: abc123,  location_id: 335,  dev_type: field}
5. {name:    free_mem,  device_id: def456,  location_id: 335,  dev_type: roof}
6. {name:    free_mem,  device_id: ghi789,  location_id:  77,  dev_type: roof}
7. {name: temperature,  device_id: abc123,  location_id: 335,  dev_type: field}
8. {name: temperature,  device_id: def456,  location_id: 335,  dev_type: roof}
9. {name: temperature,  device_id: ghi789,  location_id:  77,  dev_type: roof}

这样的时间序列的数量以每个标签的基数的交叉积为尺度,即(# names) × (# device id) × (# location id) ×(设备类型)。一些时间序列数据库随着基数的增加而挣扎,最终限制了可以存储在单个数据库中的设备类型和设备的数量。
TimescaleDB支持窄模型,并且不像其他时间序列数据库那样受到基数限制。如果您独立地收集每个指标,则狭窄的模型是有意义的。它允许您在添加新标记时添加新指标,而不需要正式的模式更改。
但是,如果使用相同的时间戳收集许多指标,那么窄模型的性能就不那么好了,因为它需要为每个指标编写时间戳。这最终导致更高的存储和摄取需求。此外,关联不同指标的查询也更复杂,因为要关联的每个额外指标都需要另一个JOIN。如果您通常同时查询多个指标,那么将它们存储在一个宽表格式中既快又容易,我们将在下一节中介绍这一点。

宽表模型

TimescaleDB很容易支持宽表模型。在这个模型中,跨多个指标的查询更容易,因为它们不需要join。此外,摄取速度更快,因为只需要为多个指标编写一个时间戳。
一个典型的宽表模型将匹配一个典型的数据流,其中在给定的时间戳中收集多个指标:

timestampdevice_idcpu_1m_avgfree_memtemperaturelocation_iddev_type
2017-01-01 01:02:00abc12380500MB72335field
2017-01-01 01:02:23def45690400MB64335roof
2017-01-01 01:02:30ghi7891200MB5677roof
2017-01-01 01:03:12abc12380500MB72335field
2017-01-01 01:03:35def45695350MB64335roof
2017-01-01 01:03:42ghi789100100MB5677roof

在这里,每一行都是一个新的读数,具有给定时间的一组测量值和元数据。这使我们能够保留数据中的关系,并提出比以前更有趣或探索性的问题。
当然,这不是一种新格式:这是在关系数据库中常见的格式。

关系数据的JOIN操作

TimescaleDB的数据模型与关系数据库还有另一个相似之处:它支持join。具体来说,可以在辅助表中存储额外的元数据,然后在查询时使用该数据。
在我们的示例中,可以有一个单独的位置表,将location_id映射到该位置的其他元数据。例如:

location_idnamelatitudelongitudezip_coderegion
42Grand Central Terminal40.7527° N73.9772° W10017NYC
77Lobby 742.3593° N71.0935° W02139Massachusetts

然后在查询时,通过连接我们的两个表,可以问这样的问题:zip_code 10017中设备的平均free_mem是多少?
如果没有连接,就需要对数据进行非规范化,并将所有元数据存储在每个测量行中。这会导致数据膨胀,并使数据管理变得更加困难。
通过连接,可以独立存储元数据,并且更容易更新映射。
例如,如果我们想要更新location_id 77的“区域”(例如,从“Massachusetts”到“Boston”),我们可以进行此更改,而无需返回并覆盖历史数据。

架构及概念

TimescaleDB是作为PostgreSQL上的扩展实现的,这意味着它在整个PostgreSQL实例中运行。扩展模型允许数据库利用PostgreSQL的许多属性,如可靠性、安全性以及与广泛的第三方工具的连接性。同时,TimescaleDB通过在PostgreSQL的查询规划器、数据模型和执行引擎中添加钩子,充分利用了扩展的高度定制性。
从用户的角度来看,TimescaleDB公开了看似单一的表(称为hypertables),它实际上是保存数据的许多单独表(称为chunks)的抽象或虚拟视图。
chunks是通过将hypertables的数据划分为一个或多个维度来创建的:所有hypertables都按时间间隔进行分区,还可以按设备ID、位置、用户ID等键进行分区。我们有时把这称为“时间和空间”的划分。

Hypertables

与数据交互的主要点是一个超表,它是跨所有空间和时间间隔的单个连续表的抽象,因此可以通过标准SQL查询它。
实际上,与TimescaleDB的所有用户交互都是使用超级表。创建表和索引、修改表、插入数据、选择数据等都可以(也应该)在超级表上执行。[跳转到基本的SQL操作]
超级表由具有列名和类型的标准模式定义,其中至少有一个列指定时间值,一个(可选)列指定额外的分区键。
单个TimescaleDB部署可以存储多个超级表,每个超级表具有不同的模式。
在TimescaleDB中创建超级表需要两个简单的SQL命令:
CREATE TABLE(使用标准SQL语法),然后是SELECT create_hypertable()。
在超级表上自动创建关于时间和分区键的索引,但是也可以创建额外的索引(TimescaleDB支持所有的PostgreSQL索引类型)。

Chunks

在内部,TimescaleDB自动将每个超表分割成块,每个块对应于特定的时间间隔和分区键空间的一个区域(使用散列)。这些分区是不相交的(不重叠的),这有助于查询规划器最小化它在解析查询时必须接触的块集。
每个块都是使用标准数据库表实现的。(在PostgreSQL内部,块实际上是“父”超表的“子表”。)
块的大小合适,确保表索引的所有b树都可以在插入期间驻留在内存中。这避免了在修改这些树中的任意位置时产生震荡。
此外,通过避免过大的块,我们可以在根据自动保留策略删除已删除的数据时避免昂贵的“真空”操作。运行时可以通过简单地删除块(内部表)来执行此类操作,而不是删除单个行。

本地压缩

压缩由TimescaleDB的内置作业调度器框架提供支持。我们利用它来跨超表异步地将单个块从未压缩的基于行的形式转换为压缩的列形式:一旦块足够老,该块将以事务方式从行形式转换为列形式。
使用本机压缩,即使TimescaleDB中的单个超表将以行和列两种形式存储数据,用户也不需要担心这一点:在查询数据时,他们将继续看到标准的基于行的模式。这类似于在解压的列数据上构建视图。
TimescaleDB通过(1)透明地将以标准行格式存储的数据附加到从列格式解压缩的数据中,以及(2)在查询时透明地从选定的行解压缩各个列来实现此功能。
在查询期间,未压缩的块将被正常处理,而来自压缩块的数据将首先被解压缩并在查询时转换为标准行格式,然后再添加或合并到其他数据中。这种方法与您期望从TimescaleDB获得的一切兼容,例如关系连接和分析查询,以及避免处理块的主动约束排除。

单节点vs集群

TimescaleDB在单节点部署和集群部署(开发中)上执行广泛的分区。虽然分区传统上只用于跨多台机器的扩展,但它也允许我们在单台机器上扩展到高写速率(和改进的并行查询)。
TimescaleDB的当前开源版本仅支持单节点部署。值得注意的是,TimescaleDB的单节点版本已经在普通机器上对超过100亿行超级表进行了基准测试,而插入性能没有任何损失。

单节点分区的优势

在单台机器上扩展数据库性能的一个常见问题是内存和磁盘之间的成本/性能权衡。最终,我们的整个数据集将无法装入内存,我们需要将数据和索引写入磁盘。
一旦数据足够大,我们无法在内存中容纳索引的所有页面(例如,b树),那么更新树的随机部分可能涉及从磁盘交换数据。像PostgreSQL这样的数据库为每个表索引保留一个b树(或其他数据结构),以便有效地找到该索引中的值。因此,当您索引更多的列时,问题会变得更加复杂。
但是,由于TimescaleDB创建的每个块本身都存储为一个单独的数据库表,因此它的所有索引只能在这些小得多的表上构建,而不是在一个表示整个数据集的表上构建。因此,如果我们适当地调整这些块的大小,我们可以将最新的表(及其b树)完全放入内存中,并避免这种交换到磁盘的问题,同时保持对多个索引的支持。


http://www.mrgr.cn/p/43865718

相关文章

golang waitgroup

案例 WaitGroup 可以解决一个 goroutine 等待多个 goroutine 同时结束的场景,这个比较常见的场景就是例如 后端 worker 启动了多个消费者干活,还有爬虫并发爬取数据,多线程下载等等。 我们这里模拟一个 worker 的例子 package mainimport (…

振弦采集仪完整链条的岩土工程隧道安全监测

振弦采集仪完整链条的岩土工程隧道安全监测 隧道工程是一种特殊的地下工程,其建设过程及运行期间,都受到各种内外力的作用,如水压、地震、地质变形、交通荷载等,这些因素都会对隧道的安全性产生影响。因此,对隧道的安…

机器学习-Gradient Descent

机器学习(Gradient Descent) videopptblog 梯度下降(Gradient Descent) optimization problem: 损失函数最小化 假设本模型有两个参数𝜃1和𝜃2,随机取得初始值 求解偏微分,梯度下降对参数进行更新 Visualize: 确定梯度方向&…

强化学习QLearning 进行迷宫游戏和代码

强化学习是机器学习里面的一个分支。它强调基于环境而探索行动、学习,以取得最大化的预期收益。其灵感来源于心理学中的行为主义理论,既有机体如何在环境给予的奖励或者惩罚的刺激下,逐步形成对刺激的预期,产生能够最大利益的习惯…

七、Kafka源码分析之网络通信

1、生产者网络设计 架构设计图 2、生产者消息缓存机制 1、RecordAccumulator 将消息缓存到RecordAccumulator收集器中, 最后判断是否要发送。这个加入消息收集器,首先得从 Deque 里找到自己的目标分区,如果没有就新建一个批量消息 Deque 加进入 2、消…

【网络安全带你练爬虫-100练】第15练:模拟用户登录

目录 一、目标1:理清逻辑 二、目标2:将每一步用代码进行表示 三、网络安全O 一、目标1:理清逻辑 模拟登录的基本流程 1、进入入口程序 2、读取目标URL 3、请求加上线程 4、确定请求数据包 5、请求格式的确认 6、数据的处理与判断 二、目标…

Shell 排序法 - 改良的插入排序

说明 插入排序法由未排序的后半部前端取出一个值,插入已排序前半部的适当位置,概念简单但速度不快。 排序要加快的基本原则之一,是让后一次的排序进行时,尽量利用前一次排序后的结果,以加快排序的速度,Shel…

深度学习与神经网络

人工智能,机器学习,深度学习,神经网络,emmmm,傻傻分不清楚,这都啥呀,你知道吗?我不知道。你知道吗?我不知道。 来来来,接下来,整硬菜&#xff1a…

vue3自定义dialog createApp setup语法组件使用element

目录 index.vue <template><el-dialogcenterv-model"isVisible"width"650px":title"title":append-to-body"true"><div id"dialogMap_container"></div><template #footer><span class&q…

Chrome浏览器中的vue插件devtools的下载方式(使用Chrome应用商店/科学上网情况下)

目录 devtools对前端来说的好处——开发预览、远程调试、性能调优、Bug跟踪、断点调试等 下载步骤&#xff1a; 测试阶段&#xff1a; 最近做项目要使用devtools这个vue插件。 devtools对前端来说的好处——开发预览、远程调试、性能调优、Bug跟踪、断点调试等 下载步骤…

IT职场笔记

MySQL笔记之一致性视图与MVCC实现 一致性读视图是InnoDB在实现MVCC用到的虚拟结构&#xff0c;用于读提交&#xff08;RC&#xff09;和可重复度&#xff08;RR&#xff09;隔离级别的实现。 一致性视图没有物理结构&#xff0c;主要是在事务执行期间用来定义该事物可以看到什…

[JavaScript游戏开发] 2D二维地图绘制、人物移动、障碍检测

系列文章目录 第一章 2D二维地图绘制、人物移动、障碍检测 第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示) 第三章 绘制冰宫宝藏地图、人物鼠标点击移动、障碍检测 文章目录 系列文章目录前言一、列计划1.1、目标1.2、步骤 二、使用步骤2.1、准备素材(…

探索AI图像安全,助力可信AI发展

探索AI图像安全&#xff0c;助力可信AI发展 0. 前言1. 人工智能发展与安全挑战1.1 人工智能及其发展1.2 人工智能安全挑战 2. WAIC 2023 多模态基础大模型的可信 AI2.1 WAIC 2023 专题论坛2.2 走进合合信息 3. AI 图像安全3.1 图像篡改检测3.2 生成式图像鉴别3.3 OCR 对抗攻击技…

环境搭建-Ubuntu20.04.6系统TensorFlow BenchMark的GPU测试

1. 下载Ubuntu20.04.6镜像 登录阿里云官方镜像站&#xff1a;阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 2. 测试环境 Server OS&#xff1a;Ubuntu 20.04.6 LTS Kernel: Linux 5.4.0-155-generic x86-64 Docker Version&#xff1a;24.0.5, build ced0996 docker-com…

【SQL应知应会】表分区(二)• Oracle版

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 分区表 • Oracle版 前言一、分区表1.什么是表分区…

Oracle 迁移 Hive 过程中遇到的问题总结

前言 最近一个小伙伴在做从 Oracle 到 Hive 的业务迁移工作,在迁移过程中属实遇到了一些坑,今天就来汇总一下这些坑,避免以后大家其他业务迁移的时候再出现类似的问题,即使出现了也可以拿过来进行对照解决。 问题1:Distinct window functions are not supported: count(…

Python案例分析|使用Python图像处理库Pillow处理图像文件

本案例通过使用Python图像处理库Pillow&#xff0c;帮助大家进一步了解Python的基本概念&#xff1a;模块、对象、方法和函数的使用 使用Python语言解决实际问题时&#xff0c;往往需要使用由第三方开发的开源Python软件库。 本案例使用图像处理库Pillow中的模块、对象来处理…

uniapp小程序,根据小程序的环境版本,控制的显页面功能按钮的示隐藏

需求&#xff1a;根据小程序环境控制控制页面某个功能按钮的显示隐藏&#xff1b; 下面是官方文档和功能实现的相关代码&#xff1a; 实现上面需要&#xff0c;用到了uni.getAccountInfoSync()&#xff1a; uni.getAccountInfoSync() 是一个 Uniapp 提供的同步方法&#xff0c…

微服务如何治理

微服务远程调用可能有如下问题&#xff1a; 注册中心宕机&#xff1b; 服务提供者B有节点宕机&#xff1b; 服务消费者A和注册中心之间的网络不通&#xff1b; 服务提供者B和注册中心之间的网络不通&#xff1b; 服务消费者A和服务提供者B之间的网络不通&#xff1b; 服务提供者…

操作系统_进程与线程(三)

目录 3. 同步与互斥 3.1 同步与互斥的基本概念 3.1.1 临界资源 3.1.2 同步 3.1.3 互斥 3.2 实现临界区互斥的基本方法 3.2.1 软件实现方法 3.2.1.1 算法一&#xff1a;单标志法 3.2.1.2 算法二&#xff1a;双标志法先检查 3.2.1.3 算法三&#xff1a;双标志法后检查 …