时序数据库
# 时序数据特点
- 所有采集的数据都是时序的
- 数据以写操作为主,读操作为辅
- 数据都是结构化的
- 数据流量平稳,可以较为准确的计算
- 一个采集点的数据源是唯一的
- 数据都有统计、聚合等实时计算操作
- 数据很少有更新或删除操作
- 数据一定是指定时间段和指定区域查找的
- 数据一般是按到期日期来删除的
- 数据量巨大,一天的数据量就超过100亿条
# 选型考虑因素
- 所有采集的数据都是时序的。在数据索引的基础上,把内存块、磁盘文件按照这样的时序的假设进行拆分,就不需要再做额外的索引,来节约时间,提升效率。
- 数据都是结构化的。计算机的编程语言更擅长处理结构化的数据,比如一个Json格式的数据过来,虽然有很多的库直接就把它解析掉了,形成我们需要的数据,但是这个过程也是比较耗时的,因为传入的时候需要进行正向的序列化,传出的时候需要进行反向的序列化,这俩次的序列化会产生很大的CPU消耗。并且结构化的数据,可以采用列式存储,虽然物联网的数据量比较大,但是变化通常都比较有规律,如果采用行式存储,压缩比率不会太高,如果采用列式存储,如001100这种数据,我们只需要记住0出现几次,1出现几次,而不需要把所有的数据都记录下来。因此,不是列式存储的数据,建议大家都不要选用。
- 一个采集点的数据源是唯一。因为时序数据最重要的特点就是每台机器产生的数据跟其它机器产生的数据在逻辑上一定是分离的,因此,可以按照分离的操作进行分表,Prometheus(普罗米修斯)和涛思数据库都是这样做的,逻辑上进行分离之后,就不需要把大量的数据混合在一起进行查询,大大提高了查询效率。
- 数据很少有更新或删除操作。可以在数据写入磁盘的时候进行优化,当数据量增大的时候(几十上百M/s的写入速度),能够达到单块磁盘极限的量,这时,一定要减小落盘后的修改,否则在修改的时候,某些数据是没有办法写入磁盘的,这时系统整体的吞吐量是不够的。
- 数据一般是按到期日期来删除的。在选型初期,很多公司不太注意压缩比,运行一段时间之后,数据越来越大,就不得不考虑数据的保存时长,如何快速的删除过期数据,这是需要考虑的问题。
- 数据以写操作为主,读操作为辅。在设计过程中要有一个优先级,需要优先满足写的操作。
- 数据流量平稳,可以较为准确的计算。有些互联网公司可能双十一的时候数据流量非常大,平时数据量相对较小,那么就不太容易估算机器的容量。
- 数据都有统计、聚合等实时计算操作。这些操作可以在数据库中进行预先计算,可以在数据库内部做,也可以在接收的时候将数据库的结果保存在一些关键步骤,这也是之前Hadoop等数据库通用的方法。
- 数据一定是指定时间段和指定区域查找的。可以把查询遍历的磁盘缩小到非常小的一部分,这是提升数据库速度的一个关键。
- 数据量巨大,一天的数据量就超过100亿条。数据库能不能支撑分离存储,新的、热的数据放在SSD中,老的数据放在HD上,或者其它更老的数据放在网络存储中。
# 时序数据库竞品比较
名称 | 特点 | 缺陷 | 备注 |
---|---|---|---|
TDengine | • 10倍以上的性能提升:定义了创新的数据存储结构,单核每秒能处理至少2万次请求,插入数百万个数据点,读出一千万以上数据点,比现有通用数据库快十倍以上。完整测试报告 (opens new window) • 硬件或云服务成本降至1/5:由于超强性能,计算资源不到通用大数据方案的1/5;通过列式存储和先进的压缩算法,存储空间不到通用数据库的1/10。 • 全栈时序数据处理引擎:将数据库、消息队列、缓存、流式计算等功能融为一体,应用无需再集成Kafka/Redis/HBase/Spark/HDFS等软件,大幅降低应用开发和维护的复杂度成本。 • 强大的分析功能:无论是十年前还是一秒钟前的数据,指定时间范围即可查询。数据可在时间轴上或多个设备上进行聚合。即席查询可通过Shell, Python, R, MATLAB随时进行。 • 与第三方工具无缝连接:不用一行代码,即可与Telegraf, Grafana, EMQ, HiveMQ, Prometheus, MATLAB, R等集成。后续将支持OPC, Hadoop, Spark等,BI工具也将无缝连接。 • 零运维成本、零学习成本:安装集群简单快捷,无需分库分表,实时备份。类标准SQL,支持RESTful,支持Python/Java/C/C++/C#/Go/Node.js, 与MySQL相似,零学习成本。 | • 比较复杂的sql功能还不支持,超级表等概念在使用时有歧义(反正我有) • 从测试报告的结果看,tdengine的WAL只是写缓存,没有真正刷到磁盘上。 • TD在快速的版本迭代过程中,难免会有一些问题不能第一时间解决(需要提Issue,社区版的解决速度也会比预期的要慢一些),所以在实际使用中,会频繁的进行版本升级。 • 轻量级的社区版免费,高可靠和线性扩展的企业版收费 • 没有互联网大厂背书。 | • 数据量:7k亿/y — 1w测点 — 1700客户测点;1亿数据量 500~600m • 超级表一年一个。一个点位一个子表 • 小项目免费、大项目收费 • 网关直接写入,复杂数据处理 → 内存Python处理,写完释放 2台7w服务器,全配SSD |
influxdb | 官方给出的单机版的数据要求: 1. 写入:每秒不超过 750,000 次的字段写入 2. 查询:每秒不超过 100 个中等查询( 有多个函数和一两个正则表达式、有group by 或多个星期的时间范围) • 数据量: 不超过 10,000,000 个系列的基数机器配置,参考官方建议如下,磁盘必须是SSD,否则性能得不到保证。 | 1. 开源版本没有集群功能 2. 存在前后版本兼容问题 3. 存储引擎在变化 | 使用InfluxDB单机社区版来支撑目前的实时异常检测业务,数据存储时间不超过3个月,应该问题不大。需要做好集群状态监控和数据备份,保障单机状态宕机最小损失。 |
DolphinDB | 高性能、分布式,支持快速存储、检索、分析及计算提供一站式解决方案 | 完全收费,适用于金融领域 | |
ES | 集群化、易于使用,适合多种分析查询应用场景 | 功能和性能上与专业时序数据库有很大的差距 | |
Prometheus | 独立地开源监控系统和告警工具,广泛应用于Kubernetes生态 |
# TDengine基本概念
给一个数据采集点建表,需要通过超级表建表,而不是建立普通表。
- 采集量 ⇒ 传感器、设备、其他类型的采集点采集的物理量。
- 标签 ⇒ 传感器、设备、其他类型采集点的静态属性,不随时间变化。
- 数据采集点 ⇒ 按照预设时间周期或受事件触发采集物理量的硬件或软件。
- 表 ⇒ 一个数据采集点一张表
- 超级表 ⇒ 某一特定类型的数据采集点的集合
- 子表 ⇒ 通过超级表创建的表
- 库 => 库是指一组表的集合。TDengine 容许一个运行实例有多个库,而且每个库可以配置不同的存储策略。不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小,是否允许更新数据等等。为了在各种场景下 TDengine 都能最大效率的工作,TDengine 建议将不同数据特征的超级表创建在不同的库里。
提示
一个库里,可以有一到多个超级表,但一个超级表只属于一个库。一个超级表所拥有的子表全部存在一个库里。
# 开发指南
开发一个应用,如果你准备采用 TDengine 作为时序数据处理的工具,那么有如下几个事情要做:
- 确定应用到 TDengine 的连接方式。无论你使用何种编程语言,你总是可以使用 REST 接口, 但也可以使用每种编程语言独有的连接器进行方便的连接。
- 根据自己的应用场景,确定数据模型。根据数据特征,决定建立一个还是多个库;分清静态标签、采集量,建立正确的超级表,建立子表。
- 决定插入数据的方式。TDengine 支持使用标准的 SQL 写入,但同时也支持 Schemaless 模式写入,这样不用手工建表,可以将数据直接写入。
- 根据业务要求,看需要撰写哪些 SQL 查询语句。
- 如果你要基于时序数据做轻量级的实时统计分析,包括各种监测看板,那么建议你采用 TDengine 3.0 的流式计算功能,而不用额外部署 Spark, Flink 等复杂的流式计算系统。
- 如果你的应用有模块需要消费插入的数据,希望有新的数据插入时,就能获取通知,那么建议你采用 TDengine 提供的数据订阅功能,而无需专门部署 Kafka 或其他消息队列软件。
- 在很多场景下(如车辆管理),应用需要获取每个数据采集点的最新状态,那么建议你采用 TDengine 的 Cache 功能,而不用单独部署 Redis 等缓存软件。
- 如果你发现 TDengine 的函数无法满足你的要求,那么你可以使用用户自定义函数(UDF)来解决问题。
# 整体架构
单元名称 | 概述 | 功能 |
---|---|---|
物理节点(pnode) | 独立运行、拥有自己的计算、存储和网络能力的计算机,可以是安装有 OS 的物理机、虚拟机或 Docker 容器 | 一个物理节点(一台物理机、虚拟机或容器)可以运行多个实例,或有多个数据节点。 |
数据节点(dnode) | TDengine 服务器侧执行代码 taosd 在物理节点上的一个运行实例 | dnode 包含零到多个逻辑的虚拟节点(vnode),零或者至多一个逻辑的管理节点(mnode),零或者至多一个逻辑的弹性计算节点(qnode),零或者至多一个逻辑的流计算节点(snode);每个 dnode 上至多有一个 mnode,由所属的数据节点的 EP 来唯一标识。每个 dnode 通过内部消息交互自动获取整个集群中所有 mnode 所在的 dnode 的 EP。 |
虚拟节点(vnode) | 更好的支持数据分片、负载均衡,防止数据过热或倾斜,数据节点被虚拟化成多个虚拟节点 | 每个 vnode 都是一个相对独立的工作单元,是时序数据存储的基本单元,具有独立的运行线程、内存空间与持久化存储的路径。一个 vnode 只属于一个 DB,但一个 DB 可以有多个 vnode。一个 vnode 除存储的时序数据外,也保存有所包含的表的 schema、标签值等。一个虚拟节点由所属的数据节点的 EP,以及所属的 VGroup ID 在系统内唯一标识,由管理节点创建并管理。 |
管理节点(mnode) | 一个虚拟的逻辑单元,负责所有数据节点运行状态的监控和维护,以及节点之间的负载均衡,也负责元数据(包括用户、数据库、超级表等)的存储和管理 Meta Node | mnode 支持多副本,采用 RAFT 一致性协议,保证系统的高可用与高可靠,任何数据更新操作只能在 Leader 上进行。mnode 集群的第一个节点在集群部署时自动完成,其他节点的创建与删除由用户通过 SQL 命令完成。 |
计算节点(qnode) | 一个虚拟的逻辑单元,运行查询计算任务,也包括基于系统表来实现的 show 命令 | 集群中可配置多个 qnode,在整个集群内部共享使用。qnode 不与具体的 DB 绑定,即一个 qnode 可以同时执行多个 DB 的查询任务。 |
流计算节点(snode) | 一个虚拟的逻辑单元,只运行流计算任务 | 集群中可配置多个 snode,在整个集群内部共享使用。snode 不与具体的 stream 绑定,即一个 snode 可以同时执行多个 stream 的计算任务。 |
虚拟节点组(VGroup) | 不同数据节点上的 vnode 可以组成一个虚拟节点组(vgroup) | 采用 RAFT 一致性协议,保证系统的高可用与高可靠。写操作只能在 leader vnode 上进行,系统采用异步复制的方式将数据同步到 follower vnode。 |
上次更新: 2025/03/09, 15:45:50