码住!详解时序数据库不同分类与性能对比
加速发展中的时序数据库,基于不同架构,最流行的类别是?
作为管理工业场景时序数据的新兴数据库品类,时序数据库凭借着对海量时序数据的高效存储、高可扩展性、时序分析计算等特性,一跃成为物联网时代工业领域颇受欢迎的数据库。
从诞生到发展至今,时序数据库应用的关键技术也在不断进步。其中,管理海量时序数据,为其适配灵活、高压缩、支持高读写性能的存储架构便是亟需解决的难点之一。
根据存储架构的不同,时序数据库可以进一步分类。本文将详细解析三种不同存储架构下,每一类时序数据库的特点,及其对时序数据的读写、压缩等性能。
三类时序数据库的存储架构分类、代表性系统与性能对比
01
基于关系型数据库的时序数据库
在没有专门管理时序数据的数据库之前,人们通常使用关系型数据库管理时序数据。
关系型数据库通常基于 B+tree 数据结构,这种数据结构在处理单个时间序列的批量数据写入时具有很高的性能。但是随着时序数据规模的不断增长,这种数据结构在同时处理数千、数万个时间序列的批量数据写入请求时,性能会急剧下降。
因此,在海量时序数据写入的工业场景中,关系型数据库的性能会显得捉襟见肘,并不适用。
部分时序数据库继承了关系型数据库的生态优势,如原生支持标准 SQL 语法,并通过扩展关系型数据库以优化时序数据存储。这类时序数据库在数据写入后建立针对时序数据的表模型,并按时间分区进行数据点的分区存储和压缩,最终写入关系型数据库中。
该类时序数据库的典型代表如 TimescaleDB,其通过扩展关系型数据库 PostgreSQL 实现时序数据管理。TimescaleDB 通过在 PostgreSQL 的查询计划器、数据模型和执行引擎添加钩子,可以构建高度定制化的扩展层。基于该扩展模型,TimescaleDB 可以利用 PostgreSQL 的多个属性,例如可靠性、安全性以及丰富的第三方工具。
总结来看,基于关系型数据库的时序数据库提供了全部的 SQL 功能,但由于无法避免时序数据场景中不需要的事务保证,对读写性能具有较大副作用。且由于关系型数据库基于行式存储构建时序数据的表模型,对于测点数、数据量大的时序数据来说,写入速度和压缩比相比采用列式存储的时序数据库,会有较大的差距,其分布式架构的可扩展性也存在短板。
02
基于 KV 存储的时序数据库
基于 KV (key-value)存储的时序数据库,通过扩展 NoSQL 数据库实现时序数据存储,其将写入的时序数据解析后,构建成 KV 模型,并以 KV 形式将数据持久化在分布式文件系统上。一组键值对中,key 是由测量指标、标签组合、测量字段键构成,value 则是由测量字段值和时间戳构成。
该类数据库的代表是 OpenTSDB,其使用了日志结构合并树(log structured merge tree,LSM-tree)的数据结构。这是一种针对写入密集的工作负载优化的数据结构,非常适合时序数据写入频率高、体量大的应用场景。
LSM-tree 结构由三部分组成:预写日志(WAL)、内存表(分为可变内存表和不可变内存表)和排序字符串表(sorted string table,sstable)。
在此结构下写入或更新数据时,每条 KV 数据将以追加的方式写入预写日志(WAL),相同的数据也被再次写入可变内存表中,这个内存表也就是时序数据的缓存表。当可变内存表的大小达到阈值后,会变成不可变内存表,并首先对其缓存的数据按照 key 的字典顺序排序,然后将排序后的 KV 数据以数据块的形式顺序写入 sstable 文件。
需要注意的是,LSM-tree 层级(level)中只能容纳一定大小的 sstable 文件,不同文件之间可能存在 key 范围重叠的情况,这时会触发合并操作。数据库会将当前层级中与下一层级中存在 key 范围重叠的 sstable 文件合并写入一个新的 sstable 文件。
总体而言,基于 KV 存储的时序数据库运用 LSM-tree 结构,具有高通量写入的天然性能优势,再加上使用了分布式文件系统,因此具有很高的扩展性。
但是这类数据库也存在一定的问题。由于合并操作的存在,相同的数据会在不同层级之间重复写入,因此产生了写放大问题,从而导致数据的写入吞吐量降低。同时,时序数据通常具有多个标签组合,当标签集的数据量增加时,基于标签组合的 key 的数量会急剧膨胀,而 key 通常是在内存中索引的,所以内存资源占用也会急剧增加。
03
原生时序数据库
原生时序数据库是面向时序数据存储全新研发的时序数据库。该类型时序数据库不依赖第三方存储,使用列式存储,提供极致的数据写入、查询和压缩能力,部署和运维更加简单。
从下图可以看出,这类数据库灵活运用了时序索引、数据缓存、数据分区、预写日志等多类设计,在存储结构 LSM-tree 的基础上,旨在全面提升全链路的时序数据管理性能。
原生时序数据库的代表是 InfluxDB 和 IoTDB。InfluxDB 在其类似 LSM-tree 的 TSM-tree 结构中,引入了 series-key 的概念,根据时间特征对数据实现了很好的分类,从而有效减少了冗余存储,提高了数据压缩率。
IoTDB 则依靠自研的时序数据标准文件格式 Apache TsFile,为其写入、压缩、查询的优异性能提供了良好的基础。TsFile 是 IoTDB 的底层数据文件存储格式,其结构分为数据区与索引区,通过索引区的文件级索引,并仅将必要的数据列加载到内存中,TsFile 可实现海量序列低延迟查询;通过数据区的多种分段摘要信息,TsFile 能够保障 IoTDB 的数据过滤、聚合性能。
同时,TsFile 支持列式存储,并采用二阶差分编码、游程编码(RLE)、位压缩和 Snappy 等先进的编码和压缩技术,优化时序数据的存储和访问,实现时序数据高压缩比,相比 InfluxDB 磁盘空间占用可降低 80%。TsFile 也支持对时间戳列和数据值列进行单独编码,以达到更好的数据处理效能。
基于 TsFile 文件格式,IoTDB 进一步自研构建了顺乱序分离引擎 IoTLSM。当新数据写入时,首先记入预写日志(WAL),通过 IoTDB 独有的顺乱序判断机制,将这个数据分到顺序空间或乱序空间。
如果数据分到顺序空间,并触发刷盘,存储引擎会直接将数据文件刷到最高层,这便对顺序数据实现了最优先、最优化的处理。如果数据分到乱序空间,IoTDB 会通过多种空间类合并、跨空间合并方法消除乱序文件,从而解决了工业场景出现乱序数据、影响写入性能的痛点。
最后,对于前文提到的 LSM-tree 结构合并操作导致的写放大问题,IoTDB 的存储引擎结构也会明显地降低数据的写入次数、保障数据的高吞吐性能。可见,原生时序数据库在保障性能表现的基础上,通过其特性的各类技术,对于前文类型中数据库的结构痛点也能够进行优化。
04
总结
时序数据库的打造是一个系统工程,单个算法和机制不能决定一个时序数据库的性能和用户体验,需要将各个优化算法和处理机制统一融合到一个整体的系统中,来提高时序数据库的读写、压缩性能,其中也经常需要在不同技术之间进行权衡、互相补充。在时序数据库的众多架构路线中,原生时序数据库架构在迭代中受到的限制更小,能够更快地进行演进,这也是此类数据库最为流行的原因。
尽管时序数据库已经实现一些突破,但相关核心技术仍在飞速发展中,可以预见未来将有更多更新颖的架构、方法被提出,不妨祝愿现有的各类时序数据库产品加速发展,期待未来有更多高性能、高稳定性的新型产品出现,从而更好地挖掘急剧增加、亟待管理的工业数据价值。
相关文章:

码住!详解时序数据库不同分类与性能对比
加速发展中的时序数据库,基于不同架构,最流行的类别是? 作为管理工业场景时序数据的新兴数据库品类,时序数据库凭借着对海量时序数据的高效存储、高可扩展性、时序分析计算等特性,一跃成为物联网时代工业领域颇受欢迎的…...
【C/C++】实参与形参的区别
在编程中,形参(形式参数)和实参(实际参数)是函数调用中的两个基本概念,它们在函数定义和函数调用中扮演着不同的角色。 形参(Formal Parameters): 形参是在函数定义时声明…...

---异常---
我们在运行程序时总遇到各种与报错,数组越界,空指针的引用,这些在java中都称为异常 对于不同的错误都具有一个与他对应的异常类来秒描述 这是对于数组越界这个类里有的方法,这些是描述异常的 在java中有一个完整的描述异常的类的…...

python如何终止程序运行
方法1:采用sys.exit(0),正常终止程序,从图中可以看到,程序终止后shell运行不受影响。 方法2:采用os._exit(0)关闭整个shell,从图中看到,调用sys._exit(0)后整个shell都重启了(RESTAR…...
网络:用2个IP地址描述一个连接
用2个IP地址描述一个连接。这是在阅读了《TCP/IP指南》后的感想,与工业标准不同,需注意区分。 如果一个IP地址有48位,则用96位描述一个连接 对于单播,是每个IP分别描述位置。位置包括:邮局编号主机编号,采用…...
Nodejs--构建web应用
构建web应用 将从http模块中的服务器端中的request使劲按开始分析,request时间发生于网络连接建立,客户端想服务器发送报文,服务器解析报文,发现http请求的报文的时候,在出发request事件之前,已经准备好Se…...
C++ 二分查找法【面试】
在C中实现二分查找法是一个常见的面试问题。二分查找法是一种在有序数组中查找特定元素的算法,其时间复杂度为O(log n)。以下是使用C实现二分查找的示例代码: #include <iostream> #include <vector>// 二分查找法函数 int binarySearch(co…...
【Docker】docker-compose常用的构建docker容器的yml文件
docker-compose的简单使用方法,在准备好的文件夹中,mkdir好要挂载的如data或者conf文件夹,及vim docker-compose.yml,将下方的要使用的内容粘贴进去,根据自己需要添加/删除/修改一下。最后在当前文件夹直接后台启动即可…...
华为坤灵路由器初始化开局的注意事项,含NAT配置
坤灵路由器比较坑,无web界面,全程命令行配置,但是版本更新导致和华为企业路由器配置很多不一样的地方,今天介绍下 1、aaa密码复杂度修改: #使能设备对密码进行四选三复杂度检查功能。 <HUAWEI>system-view […...

HTTP!!!
HTTP 一 : 请求报文1.2 : 首行1.3 :请求头(header)1.4 : 空行1.5 : 正文 body 二: 响应报文2.2 : 首行 三 : URL 一 : 请求报文 一个HTTP 请求报文, 分成四个部分 首行 GET https://cn.bing.com/?FORMZ9FD1 HTTP/1.1请求头(header)空行正文(body) 1.2 : 首行 首行又分为三个…...

Mybatis用Map接收返回值可能出现的问题
先看一个示例 明明定义了Map<String,String> 实际内部存放的是Integer resultType是Map 也就是说Mybatis是通过反射将类型放进去的 躲过了编辑器检查 但是这样取值时候就会报类型转换错误 解决方式 resultMap 另外一种方式 用Number Integer和Double的父类 Ma…...

Web爬虫--fofa-资产信息搜集
免责声明:本文仅做技术交流与学习... 目录 fofa.py fofa搜索参数分析 fofa_api.py fofa.py import requests from bs4 import BeautifulSoup# 登录fofa之后,把自己的cookie弄过来. header{cookie: } # 参数为搜索的语法. urlhttps://fofa.info/result?qbase64dGl0bGU9IuS4…...

mySql的事务(操作一下)
目录 1. 简介2. 事务操作3. 四大特性4. 并发事务问题5. 脏读6. 不可重复读7. 幻读事务隔离级别参考链接 1. 简介 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作…...

UniApp或微信小程序中scroll-view组件使用show-scrollbar在真机Android或IOS中隐藏不了滚动条的解决办法
show-scrollbar 属性 不论是使用 变量 还是直接使用 布尔值或者直接使用 css 都是在 ios、Android 上是都没有效果。。 真机中还是出现滚动条 解决办法 添加下面CSS ::-webkit-scrollbar {display: none;width: 0 !important;height: 0 !important;-webkit-appearance: no…...

每天五分钟深度学习框架pytorch:多维tensor向量在某一维度的拼接和分割
本文重点 在深度学习中,我们常常需要完成多个向量拼接,同时也要完成向量的分割,在pytorch中已经有封装好的库,我们可以直接调用完成这部分任务。 Cat拼接 c=torch.cat([a,b],dim=0)表示将a和b按0维度进行拼接,需要注意再非dim维度,两个矩阵的维度必须是一致的,不然会拼…...
从C语言到C++(五)
从C语言到C(五) 自动类型推导尾拖返回类型类型信息推导typeid1. 定义和基本作用2. 使用方法3. 注意事项4. 示例代码5. 关联概念:RTTI decltype基本用法示例注意事项总结 基于范围的增强for循环示例 1:使用数组示例 2:使…...

数据结构——栈(Stack)详解
1. 栈(Stack) 1.1 概念 栈:一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中数据元素遵循后进先出LIFO(Last In First Out)的原则 压栈&am…...

1.Element的table表高度自适应vue3+js写法
解决方法 在页面table上添加id,动态计算每页table的最大高度 ,将高度保存在store中,每次切换路由时进行计算。 文章目录 解决方法前言一、页面table使用二、store状态库1.引入库 效果 前言 提示:状态管理使用的是pinia,用法参考…...

联想电脑电池只能充到80%,就不在充电了,猛一看以为坏了,只是设置了养护模式。
现在电池管理模式有三种: 1)常规 2)养护 3)快充 好久没有用联想的电脑了,猛一看,咱充到了80%不充了,难道电池是坏的?我们要如何设置才可以让其充电到100%呢? 右下角…...

Unity接入PS5手柄和Xbox手柄以及Android平台的(以及不同平台分析)
Unity接入PS5手柄和Xbox手柄以及Android平台的(以及不同平台分析) 介绍Unity手柄小知识PC端和编辑器上的摇杆事件和滑动事件PS5手柄Xbox手柄北通手柄 安卓环境下(安卓手机或者安卓模拟器)PS5手柄Xbox手柄北通手柄 总结 介绍 最近…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...