最近在一个制药车间的数据采集项目里,被客户问得最多的问题就是:工业数据到底该存哪里?现场设备有PLC、有传感器、有DCS系统,点位加在一起一万出头,每天产出的数据按亿来计算。一开始大家想的都是MySQL,结果一个月的记录就有几亿行,查询慢得没法看。再往上是Hadoop,可现场IT就两三个人,养不起也不愿意养一套大数据平台。最后所有目光都锁定在两个名字上:InfluxDB和TDengine。
这两个都是时序数据库,但它们的思路、架构、部署方式和成本结构差别非常大。我花了两周时间,把两个库都在真实工业数据场景里跑了一遍,从部署、写入、查询到授权成本逐项做了对比。这篇文章不吹谁不黑谁,只说我实际操作的感受和踩过的坑,给同样在做工业数据选型的朋友一个参考。
1. 先把场景说清楚:工业数据到底“长什么样”
1.1 三个“不一样”:高基数、高频写、长保留
工业数据和互联网业务的日志数据完全是两回事。互联网场景里,一条日志可能有几KB甚至几十KB,字段多、结构乱,查询时往往要全文检索。工业数据反过来,每条记录就一个时间戳加几个数值,非常短,但量极其大,而且写进来之后很少会改,基本都是按时间顺序追加。
最要命的是基数问题。一台设备有几十个测点,一个车间几十台设备,一个工厂几百台设备,算下来tags组合轻松上万。InfluxDB管这种组合叫series cardinality,一旦这个数字涨上去,内存就像漏水一样往下掉。TDengine的模型则是一张表对应一个测点,设备再多也只是表的数量多,不会引起索引爆炸。
还有一个特点是保留周期长。安全规程要求很多生产数据保留一年甚至三年以上。数据量乘以保留周期,存储成本一下子就上来了。所以选型时压缩率是一个非常关键的指标,不能只看写入速度。
1.2 为什么MySQL、Hadoop撑不住工业现场
MySQL不是不能存时序数据,是存到一定量级之后查询完全扛不住。几亿行数据在那张表里,就算加了索引,做一次区间聚合也要几秒钟。工业现场的操作工和工艺员不可能接受这种延迟。而且MySQL的压缩能力基本没有,原始浮点数据一存就是8个字节一个数,存储成本吃不消。
Hadoop生态倒是什么都能存,但太重了。HBase、Kafka、Flink这一套下来,光集群维护就得专门配一个人。很多工厂的IT部门连DBA都没有,更别提大数据工程师。用Hadoop存时序数据,就像为了开个便利店买了一辆重型卡车,成本全耗在运输和维护上了。
时序数据库解决的正是这个夹缝问题:写入吞吐量要高、查询响应要快、压缩率要好、部署和维护要轻。InfluxDB和TDengine都是这个赛道里的代表,但它们解决问题的路径完全不同,这正是值得做对比的地方。
2. 底层架构拆开看:两边处理数据的思路完全不一样
2.1 InfluxDB:按“时间分片+倒排索引”的通用时序引擎
InfluxDB的存储引擎在1.x时代叫TSM,本质是LSM树的一个变种。数据先写内存里的write-ahead log和内存索引,攒够一批再落盘,后台做compaction合并。LSM的好处是写入特别快,顺序写就行,缺点是compaction有放大效应,读的时候可能要查多个文件,高基数下索引占内存的问题尤其明显。
InfluxDB的数据模型是measurement加tag加field。measurement类似表,tag是带索引的标签,field是实际数值。每一条不同的tag组合都会在内存里生成一个series索引。打个比方,series数量从1万涨到10万,内存占用不是线性涨,是指数级涨。我测试时只模拟了2000台设备乘20个测点,内存就涨了将近8个GB,这个膨胀速度在真实工业场景里是很让人担心的。
查询方面InfluxDB提供了InfluxQL和Flux两套语法。Flux功能确实强大,能做管道式流处理,但学习曲线陡,很多从SQL转过来的人看到Flux就头疼。我自己用下来,InfluxQL处理常规聚合够用了,但一旦涉及复杂的跨表计算,Flux绕来绕去的函数式写法还是挺费劲的。
2.2 TDengine:一张表对应一个测点的数据模型
TDengine的思路跟InfluxDB完全不是一个路子。它的核心是一张表记录一个数据采集点,表名就是设备编号加测点编号。因为同一张表里的数据全部来自同一个测点,时间戳天然有序,数据在磁盘上就是顺序排列的连续块,查询时直接按时间区间做顺序扫描,效率极高,也不需要维护倒排索引。
为了管理成千上万张表,TDengine设计了超级表STable。超级表定义好schema和tags模板,底下挂的子表自动继承。比如我建一张名叫meter的超级表,tags里放device_id和location,然后为每台设备建立一张子表。查询时用一条SQL可以跨所有子表做聚合,也可以指定tag条件只查某一台设备,非常贴合工业现场的按设备、按区域筛选的需求。
写入路径上TDengine省掉了LSM的compaction过程。数据落盘之后就是有序的,不需要反复合并,CPU和IO开销都小。这带来的直接好处是同等硬件下写入吞吐更高、查询更快,磁盘占用也更可控。再加上它对标准SQL的支持,团队的维护门槛会比Flux低不少。
2.3 关键差异速查:数据模型、写入路径、压缩方式
| 对比维度 | InfluxDB | TDengine |
|---|---|---|
| 数据模型 | measurement + tag + field,按tag组合生成series | 库 + 超级表 + 子表,一张子表对应一个测点 |
| 存储结构 | LSM树变种TSM,按时间分shard,后台compaction | 每张表独立有序存储,时间驱动,天然避免compaction放大 |
| 索引机制 | 内存倒排索引,series cardinality大会爆内存 | 无需倒排索引,按tag检索子表,内存占用平稳 |
| 写入协议 | Line Protocol文本协议 | SQL / RESTful / 多种SDK,支持批量写入 |
| 查询语言 | InfluxQL + Flux | 标准SQL,带时序函数扩展 |
| 压缩策略 | 列级压缩,受tag基数影响 | 块级压缩,同一测点连续存储,压缩率稳定 |
| 集群能力 | 开源版仅单机,企业版支持集群 | 社区版自带多节点集群能力 |
| 典型场景 | 监控、可观测性、通用时序存储 | 工业物联网、设备数据中台、工厂级SCADA |
这张表做出来之后,选型方向基本就清晰了。如果场景偏监控和可观测性,InfluxDB的生态和查询灵活性更顺手;如果场景是纯粹的工业设备数据采集、存储、聚合分析,TDengine的模型天然更匹配。
3. 真实落地部署:从零开始把两个库跑起来
3.1 从零部署TDengine社区版:Linux与Windows集群
TDengine社区版这几年的迭代很活跃,官网上直接下载安装包就行,GitHub上也有release。Linux部署非常简单,解压之后执行install.sh,systemctl启动taosd,再用taos命令行连上去建库建表。Windows版本就是图形化安装,装完之后命令行执行taos也能连上。
这里重点说一下Windows集群部署,因为很多人一上来就在Windows上搞多节点,容易栽跟头。TDengine的集群通信依赖FQDN解析,所以每台机器的hosts文件必须写清楚所有节点的IP和主机名。节点之间通信走6030端口,taosAdapter走6041端口,Windows防火墙如果没放行这两个端口,集群永远显示离线。我第一次搭三节点集群时,就是被防火墙卡了半小时,后来发现两个节点之间基础连通性测试没问题,但taosAdapter数据一直传不过去,最后放行端口才恢复。
部署完之后建库建表,这是我实际执行过的SQL:
-- 创建数据库,保留365天,每10天一落盘 CREATE DATABASE factory KEEP 365 DURATION 10 BUFFER 32 WAL_LEVEL 2; USE factory; -- 创建超级表,tags记录设备编号和位置 CREATE STABLE meter ( ts TIMESTAMP, val FLOAT, status INT ) TAGS ( device_id INT, location BINARY(32) ); -- 为每台设备建立子表 CREATE TABLE d_1001 USING meter TAGS (1001, 'Line-A'); CREATE TABLE d_1002 USING meter TAGS (1002, 'Line-A');这里几个参数值得解释一下。KEEP决定了数据保留周期,超过这个时间老数据会被自动清理,工业场景建议按实际合规要求设置。DURATION是数据落盘的子文件时长,10代表每10天生成一个新数据文件,这个值会影响查询时扫描的文件数量。BUFFER是内存缓冲块数,32是默认值,写并发高时可以往上调。WAL_LEVEL控制WAL的刷盘级别,2表示每次写入都刷盘,对数据安全要求高的场景必须用这个配置。
写数据可以用taosBenchmark做压力测试,也可以直接用SQL插入。生产环境建议走taosAdapter提供的RESTful接口或者Java/Python SDK,批量写入时单次插入几千条性能最好。
3.2 InfluxDB部署与influxdb studio可视化
InfluxDB这边我用的是2.7版本,Docker一键部署:
docker run -d --name influxdb \ -p 8086:8086 \ -v influxdb-data:/var/lib/influxdb2 \ influxdb:2.7启动之后浏览器访问8086端口,第一次进来设置管理员账号、组织名和初始bucket。InfluxDB 2.x把database的概念改成了bucket,写入前要先创建bucket和token,相当于API密钥。所有客户端都是拿token认证,没有token什么都查不了,这一点和TDengine默认本地无密码的策略差别很大,好处是安全默认值高,坏处是配置多了一层。
写数据我用的是Python的influxdb-client库,代码非常简洁:
from influxdb_client import InfluxDBClient, Point from influxdb_client.client.write_api import SYNCHRONOUS client = InfluxDBClient(url="http://localhost:8086", token="my-token", org="factory") write_api = client.write_api(write_type=SYNCHRONOUS) point = Point("meter") \ .tag("device_id", "1001") \ .field("val", 23.5) \ .field("status", 1) write_api.write(bucket="factory", record=point)关于influxdb studio这个工具,它是社区常用的一款GUI客户端,能直连InfluxDB 1.x和2.x,左侧浏览bucket,右侧写InfluxQL/Flux查询,还能出简单的图表。做临时数据探查很方便,比在命令行里敲查询直观得多。我平时排查数据质量问题经常用它,比开Postman去调RESTful接口效率高不少。
写入之后查数据基本就是InfluxQL的活,比如查最近一小时的平均值:
SELECT MEAN("val") FROM "meter" WHERE time > now() - 1h GROUP BY time(5m), "device_id"功能上没问题,但每张表的tag组合一旦变多,这条查询在内存里的开销会明显放大,这就是前面说的基数隐患。
3.3 写入压测记录:同样的100台设备,两边表现如何
我在自己测试环境里做了个简单的对照实验。模拟了100台设备,每台50个测点,每秒钟各采集一次数据。这样每秒产生5000条记录,一天就是4.32亿个数据点。测试机器是8核16G的虚拟机,SSD存储,两个库都是默认配置。
TDengine这边,用taosBenchmark直接灌数据,单线程批量写入每秒能到40万条以上,CPU占用大概60%。查询最近5分钟所有设备某个测点的平均值,毫秒级返回。磁盘占用方面,50个测点连续存储加块压缩,原始浮点数据大概压到原来的15%左右,一天的数据量大约占800MB空间。
InfluxDB在同一台机器上,单线程批量写入每秒大约10万到20万条,明显比TDengine慢一截。查询同样的5分钟聚合,返回时间在几百毫秒到1秒之间,主要取决于series数量。磁盘占用和tag基数关系很大,50个测点全部做成独立field时,压缩率还行,但一旦把测点拆成tag,series数涨上去,压缩率和内存占用就同时恶化。
这个结果不意外,因为两个库的设计目标本来就不一样。InfluxDB在可观测性场景下写日志类数据很强,TDengine在面对高数量测点的工业数据时,模型优势会直接转化为硬件的成本优势。注意我说的都是单机相对值,不同版本、不同配置结果会有波动,但趋势是一致的。
4. 算一笔成本账:社区版、商业版和“到底谁更贵”
4.1 社区版和白嫖版:TDengine到底能不能免费玩
网上有不少人抱怨“TDengine太贵了”,这个说法得拆开看。TDengine确实有商业版,提供原厂技术支持、可视化运维监控、更高规格的集群支持等增值服务,这个收费是合理的。但TDengine社区版是长期开放的,日常工业场景最核心的写入、查询、超级表、多节点集群这些能力在社区版里都有,没有做暴力功能阉割。
我的理解是,社区版和商业版的边界主要在有专人服务和高可用性要求。工厂级别觉得现场不能出任何问题,买商业版相当于买保险和技术兜底。但如果只是内部做数据采集和展示,IT团队自己搞,社区版完全能用。很多抱怨贵的人,可能是拿商业版的报价和纯开源软件的免费预期去比,忽略了背后的服务价值。
实际部署时我可以负责任地说,社区版三节点集群的体验是很完整的,官方文档里关于集群部署的说明也够用。只要网络规划合理、hosts和防火墙配置正确,基本不会遇到解决不了的大问题。
4.2 InfluxDB的开源版与企业版差别在哪
InfluxDB这边要复杂一些。2.x时代的开源版叫InfluxDB OSS,是单机架构,MIT协议,功能上支持完整的读写和查询,但高可用、水平扩展、多租户、细粒度权限这些只在InfluxDB Enterprise里提供。企业版是按年订阅收费的,价格不便宜,而且部署架构也重。
到了3.x版本,InfluxDB把核心引擎换成了Apache Arrow和Parquet格式,查询引擎换成了DataFusion,设计上更偏向云原生,支持对象存储做冷热分层。3.x也有单机和集群的版本区分,但整体方向已经是云服务优先。所以如果你评估InfluxDB,一定要把“用开源版单机”和“用云服务”这两条路线分开算钱。
4.3 五年总成本估算:别被“初始免费”带偏
很多人选型只盯着软件授权费用,忽略了运维和硬件成本。我按一套中等规模的工厂数据平台来算:200台设备、每台60个测点、数据保留1年,选两台8C32G服务器做双节点,都不买商业支持。
如果是TDengine社区版:软件费用为零,硬件两台服务器大约5万,开发人员熟悉标准SQL基本没有额外学习成本,日常运维只需盯数据盘容量,五年总成本约10万出头。
如果是InfluxDB OSS单机版:软件费用为零,但单机会成为瓶颈,数据量到半年之后可能扛不住,需要换更贵的硬件或者拆多个实例,硬件成本根据基数大小波动很大。运维上还需要有人懂Flux和容量管理,这个隐性人工成本常常被忽略,五年下来可能比TDengine高出一截。
如果两边都买商业版或者上云,那价格就没边了,必须按数据写入量和存储时长来单独评估。总的来说,成本对比不能只看license,要把“两年后数据量涨了怎么办”这件事提前算进去。
5. 踩坑记录与排查速查表:这些坑我基本都替你趟过
5.1 高基数场景:InfluxDB内存暴涨的排查思路
InfluxDB内存飙升几乎是高基数场景的必经之路。排查时先用这个命令看当前series基数:
SHOW SERIES CARDINALITY如果结果显示基数已经到几十万甚至上百万,内存不爆才怪。这时候要回到数据模型上做减法:能放进field的字段不要设计成tag,tag值尽量保持低位。但工业场景里设备数量就是多、测点就是多,模型再怎么优化也绕不开高基数的物理现实。所以这个阶段我通常会反问自己一个问题:这个场景是不是硬要用InfluxDB,还是该考虑换TDengine那张表一个测点的模型。
5.2 TDengine常见写入与集群问题实录
TDengine这边我踩过的坑主要集中在写入和集群。写入方面,批量插入时单条SQL的values条数太多会报错,控制在一个合理范围比如每批几千条就行。还有乱序数据问题,如果采集端偶尔有延迟,数据到达顺序乱了,写进去会很慢,因为TDengine默认假设数据大致按时间顺序到达。解决方法是先在前端做缓冲排序,尽量减少乱序程度。
集群方面,最大的坑是FQDN解析。TDengine节点之间通信靠主机名而不是IP,所以hosts文件必须配置正确。Windows集群尤其要注意,Windows的hosts文件路径和Linux不一样,改完还要刷新DNS缓存。另外6030和6041两个端口缺一不可,6041只是RESTful接口,但很多工具和连接器都靠它,防火墙漏放这个端口会导致“查询正常但数据写入超时”这种奇怪现象。
5.3 备份、迁移与时区问题速查表
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 查询结果偏移8小时 | 客户端时区与存储时区不一致 | 统一使用UTC存储,展示层按本地时区转换 |
| TDengine集群某节点离线 | FQDN解析失败或防火墙拦截 | 检查hosts、放行6030/6041端口 |
| InfluxDB内存持续上涨 | series cardinality过高 | SHOW SERIES CARDINALITY定位,重构tag/field模型 |
| TDengine写入报“乱序数据” | 采集端数据延迟到达 | 前端增加时间戳缓冲,尽量按序写入 |
| 批量插入报错 | 单条SQL行数过多 | 拆成小批次,每批控制千条级别 |
| 需要迁移数据 | 版本升级或换库 | TDengine用taosdump导出,InfluxDB用influx backup/restore |
关于备份多说一句,时序数据库的数据量非常大,常规的mysqldump逻辑备份完全不适用。TDengine的taosdump支持逻辑导出,适合中小规模库;大规模场景建议直接做数据目录的物理快照,恢复会快很多。InfluxDB 2.x的backup命令是按bucket做的,恢复时要注意bucket名字不能重复,否则会报already exists。
时间问题看起来小,但工业现场特别容易踩。采集端PLC给的时间戳如果带时区,而数据库端默认UTC,查询结果就会整体偏移8小时。处理办法很简单,但一定要在建模初期定好规范,别等到报表对不上了再回头改,数据已经写进去几亿条,改起来就是灾难。
最后说句实在话
数据库选型这事没有标准答案。我个人在实际项目里更看重团队运维能力和现场网络约束:如果工厂IT薄弱、点位多、要求部署简单,TDengine社区版往往是首选;如果团队本身熟悉InfluxQL、已经有监控技术栈,那InfluxDB的生态更省心。还有一个建议,别光看跑分和文档,先把两个库在边缘网关或测试服务器上跑一个月真实数据,用实际的写入量、查询模式、保留周期做压测,再决定上产线。工业数据动辄上亿条,选错了再迁移,代价远比你想象的大。