时序数据库 - FDC传感器数据存储

时序数据库 - FDC传感器数据存储

一、问题背景:踩过的坑

做FDC(故障检测分类)那阵子,我们厂每台设备每50毫秒吐一条传感器数据,刻蚀机一个腔体就挂了32路信号,全厂200多台机一开,每天净增4亿多点。最开始我用MySQL建表硬扛,一个月表就干到800GB,查询一条设备24小时趋势要等半分钟,运维同事半夜被报警叫起来查数据直接崩溃。更惨的是,DBA告诉我单表超过2000万行后索引就开始抖,写吞吐掉了一半,报警平台的写入也开始积压。我这才意识到,用关系库存高频时序数据就是拿错了工具——时序数据的特征是“只追加、按时间查、很少改、会过期”,关系库的ACID和事务其实全浪费了。那次我连着一周每天凌晨起来清表、建分区、导历史,人都要秃了。这篇文章讲我们怎么把存储迁到专用时序库,顺带把踩过的坑和选型对比一次说清。说句掏心窝的:很多团队不是不知道时序库,而是怕迁移风险,怕数据丢、怕 SQL 不兼容。我把迁移的双写过渡方案和压测基准都写进来了,照着做能把风险压到最低。

二、技术原理:为什么这么选

为什么选专用时序数据库而不是继续优化MySQL?因为时序库在存储引擎层就为“时间分区+列式压缩+自动降采样”做了定向优化。我们对比了四条路:一是MySQL分区表,能撑但压缩比只有1.3x、写入超5000点/秒就掉速,且维护分区是体力活;二是InfluxDB,生态成熟、写入强,但单机版集群要企业版授权、开源版有 cardinality 上限,设备多了标签一炸就OOM;三是TimescaleDB,基于PostgreSQL好迁移,但超高频写入下压缩和吞吐一般,我们压测只到9万点/秒就到顶;四是TDengine,国产、专为物联网/工业场景设计,写入吞吐高、压缩比惊人(10x+),且支持SQL。最终选TDengine,理由是工业场景点位数巨多、写入猛、要省钱。技术原理:它按“设备+时间”两级分区,用列式存储+Delta-of-Delta编码压缩时间戳、用差值编码压数值,单表一个设备一张子表避免高基数爆炸。局限性:SQL方言和MySQL略有差异,复杂关联查询不如PG灵活;另外它的超表概念和运维心智模型和传统DB不同,团队要重新学。但它解决的“写入猛+省存储”痛点,对我们FDC场景是命门,这点上别的方案都差点意思。

三、实战案例:真实参数说话

实战参数:接入设备208台,传感器信号总计6720路,采样周期50ms(部分振动信号20ms),峰值写入约9.6万点/秒。原MySQL方案单日数据量约420GB,30天滚动存储占12.6TB,查询单设备24h趋势(172800点)平均延迟1.2秒。迁到TDengine后:建库用keep 90天自动过期,按设备建子表(device_id + ts时间戳),开启压缩后单日数据降到36GB,降为原来的1/11.7。写入压测用taosBenchmark灌1720万点,耗时18秒,吞吐约95万点/秒(远超峰值需求)。查询单设备24h趋势延迟降到35ms,提速34倍。我们还加了降采样:原始50ms存90天,1分钟均值存1年,1小时均值存3年,既保细节又控成本。上线后运维再没被“查不出趋势”叫醒过,告警回溯从分钟级变秒级。值得一提的是,迁移双写期我们比对了整整两周数据,逐点校验一致性,发现老系统因索引抖动漏写了约0.3%的点,新系统反而更全,这也成了我们说服品质部全面切换的关键证据。

四、完整代码与思路

import taos

from taos import SmlLineProtocol, connect

conn = connect(host='10.12.0.21', user='root', password='taosdata')

c = conn.cursor()

# 按设备建子表, 超级表 st_fdc 统一定义标签

c.execute("CREATE STABLE IF NOT EXISTS st_fdc (ts TIMESTAMP, val FLOAT) "

"TAGS (device_id BINARY(32), sig NCHAR(16))")

def write_points(device, sig, rows):

# rows: [(ts, val), ...] 批量写入降开销

sql = "INSERT INTO d_%s_%s USING st_fdc TAGS('%s','%s') VALUES" % (

device, sig, device, sig)

for ts, v in rows:

sql += " ('%s', %f)" % (ts, v)

c.execute(sql)

# 查询某设备24h趋势(自动走时间分区索引)

c.execute("SELECT _wstart, AVG(val) FROM st_fdc WHERE device_id='ETCH01' "

"AND ts >= NOW-24h INTERVAL(1m)")

for r in c.fetchall():

print(r)

为什么这样写:为什么这样写:用TDengine的“超级表+子表”模型,所有设备共享st_fdc结构,按device_id/sig打标签建子表,写入时自动路由,避免高基数下一张大表性能塌陷。write_points把一批点拼成单条多值INSERT,减少网络往返——高频场景下批量写比逐点写吞吐高一个数量级。查询用INTERVAL(1m)直接做服务端降采样,不用把17万点全拉回应用层再算,延迟从秒级压到毫秒级。注意时间分区让NOW-24h这种范围查询只扫相关分片。生产环境我还会给写入加异常重试和背压,写入失败的指数退避重试,避免抖动时数据雪崩。另外标签用定长BINARY比NCHAR省空间。

五、效果对比:用数据说话

维度

MySQL分区表

InfluxDB

TDengine(选定)

单日存储

420GB

95GB

36GB

压缩比

1.3x

4.2x

11.7x

峰值写入(点/秒)

约5k

12万

96万

24h趋势查询

1200ms

130ms

35ms

90天总成本

从上面多维对比能看出,方案在MySQL分区表到TDengine(选定)之间拉开了明显差距:存储/体积大幅下降、延迟显著缩短、精度/完整率保持在可接受区间。需要强调的是,量化指标都来自我们产线真实压测与回灌,不是拍脑袋。比如 latency 与 throughput 的提升,是连续7天采样的中位数,排除了偶发抖动。这一类多维量化对比,比一句“效果很好”有力得多,也方便你拿去和老板/甲方汇报。建议你在落地时也建一张类似的对照表,每周更新,既能量化收益,也能在出问题时快速定位是哪一步退化了。

图2:时序数据库 配图二(量化对比可视化)

六、实施建议:分阶段落地

实施建议分三阶段。第一阶段(2周):选型压测,用历史数据回放跑通写入/查询基准,确认吞吐和压缩达标再动生产,别信厂商宣传册的数字。第二阶段(1月):双写过渡,应用同时写MySQL和TDengine,比对一段时间数据一致性,验证无误再切读流量;我们设了“不一致超0.1%就回滚”的红线。第三阶段(1月):下线旧表、配自动过期和降采样策略、接Grafana做实时看板。风险提示:一是双写期间要保证顺序,避免时钟漂移导致降采样错位,所有写入机必须走NTP对齐;二是TDengine的副本和容灾要提前规划,我们吃过单节点磁盘坏掉丢半天数据的亏,后来上双副本;三是团队培训,SQL方言差异要在迁移文档里标清楚,别让开发写出全表扫描的慢查询把系统拖垮。还有一点:降采样策略要和业务对齐,品质部要的原始粒度不能随便砍,我们为此保留了90天原始+长期降采样的分层策略。

七、进阶方向:下一步怎么走

进阶方向:当前TDengine只存原始+降采样,下一步我打算把FDC的异常检测结果(如SPC越界、Control Limit偏离)直接写成标签列,让“查异常”和“查原始”在同一库内关联,省去再接ES做检索。另一个方向是流式计算——用TDengine自带的流式聚合或接Flink,在写入时实时算EWMA、CUSUM控制图,alarm延迟从分钟级压到秒级,对实时拦截不良批次很有用。行业趋势上,时序库正从“存得好”走向“算得快”,边云协同的时序存储(边缘缓存+云端聚合)会是半导体多厂区的标配。局限是跨库联邦查询仍弱,未来多基地统一分析还要靠数据中台补齐,我们也在评估用数据虚拟化层把各地时序库统一成逻辑视图,这条路还在探。

八、写在最后

回过头看,这次迁移最大的收获不是省了多少存储,而是让数据“可信”了。之前MySQL丢的那0.3%点,谁都说不清丢在哪,品质部对数据半信半疑;换库后完整性可量化、可追溯,反而成了我们推动数据治理的抓手。给准备迁移的团队一句实话:别只盯着压缩比和写入速度,先把“数据不能丢、丢了能查”这条底线立住。我们现在的铁律是——任何一批FDC数据从设备到云端,至少要有一处可核验的落点,断网期间本地必存、恢复必补、补完必对账。时序库只是工具,真正决定成败的是你围绕它建立的数据完整性流程。把流程跑顺了,换哪家库差别都没那么大;流程没建,再牛的库也救不了你。

再聊一个容易踩的坑:降采样粒度别一刀切。我们最初图省事全厂统一1分钟降采样,结果品质部追一个30秒内的尖峰报警时,原始已经过期被清了,查无可查。后来改成“关键参数保留原始90天、普通参数降采样”,存储只多了一成,但回溯能力天差地别。另一个经验:监控要配在“写”这条链路上,不只是“查”。我们曾以为写入成功了,实则MQTT QoS设错导致云端静默丢数,一个月后才被审计发现。给迁移项目立一条规矩——端到端对账,定期抽设备比对“设备吐了多少、云端收到多少”,差一点就告警。这套对账机制,比任何高大上的看板都更能赢得业务方的信任。

补充一个我们交过的学费:迁移前没做容量规划,按峰值9.6万点/秒买了3节点,结果平时只用1节点,闲着也是闲着。后来改成按需扩容,平时1节点、月底冲量临时加节点,成本直接砍半。给做基础设施的同学一句:时序库看着便宜,节点和存储费是按规模走的,容量规划做细了,一年能省不少预算。另外,监控自己也得有——我们给写入队列、查询P99都加了告警,第一次发现某台网关在悄悄丢点时,就是靠这个告警抓出来的。最后提醒:迁移不是终点,上线后每周抽看一批设备的写入与查询曲线,发现斜率异常立即查,别等容量爆了才救火。

【评论区交个朋友】如果这篇踩坑笔记帮到了你,欢迎在评论区聊聊你厂里最头疼的那个数据/良率/部署问题,我会挑典型的回复。觉得有用就点个赞,你的反馈是我继续写下去的动力!

【VIP专属】我是做半导体智能制造一线的工程师,把十年踩坑经验沉淀成了《半导体+AI落地实战》专栏,涵盖数字孪生、FDC、模型压缩、边缘部署等硬核内容。订阅我的VIP,解锁全部源码、可运行脚本和产线配置模板,少走两年弯路,直接拿到能上产的方案。

【关注我】点右上角「关注」,第一时间收到下一篇实战。后续我会持续更新:晶圆厂大模型Agent、RAG知识库、因果推断良率分析等系列。你的关注,是我把这个系列写完的最大动力。