当前位置: 首页 > news >正文

物联网数据存储架构:从时序数据库到时序+关系型混合存储的选型复盘

物联网数据存储架构:从时序数据库到时序+关系型混合存储的选型复盘

物联网存储的挑战不是"存得下",而是"查得快"——当你需要在1秒内从万亿条传感器数据中找到某个设备过去7天的所有异常温度点时,存储架构的选择就决定了答案。

一、问题的分层

物联网平台的数据按属性天然分为两类:

数据类型特征写入模式查询模式数据量级
时序数据时间戳+数值,不可变高频追加写时间范围+设备ID每天TB级
元数据设备属性/关系,可变低频随机写关联查询/点查百万级记录

这个划分是架构决策的基石。试图用MySQL同时解决两类问题,就是大多数物联网项目性能崩塌的根源。

二、时序数据库的深度对比

我们在同一硬件环境(3节点×32C64G×NVMe SSD)上做了全面的基准测试。

2.1 写入性能

测试数据:1000万设备,每设备每10秒上报1条(10字段),持续1小时 TDengine 3.2: ████████████████████████████████ 12,800,000 points/sec InfluxDB 2.7: ██████████ 3,200,000 points/sec TimescaleDB: ██████ 1,900,000 points/sec ClickHouse: ██████████████████████ 8,500,000 points/sec

2.2 查询延迟对比(10亿条数据规模)

查询场景TDengineInfluxDBTimescaleDBClickHouse
单设备24h数据8ms95ms120ms45ms
1000设备最新值5ms220ms180ms35ms
时间范围聚合(1h→1min降采样)120ms2800ms3400ms850ms
全表扫描(max值)3200ms超时(30s)超时(30s)5800ms
磁盘占用(压缩后)42GB128GB105GB68GB

2.3 为什么选择TDengine

5个决定性因素:

  1. "一个设备一张表"的存储模型——同一设备的数据物理连续存储,时间范围查询本质上是顺序读,这是8ms延迟的物理基础。
  2. 列式存储+两级压缩——delta-of-delta时间戳压缩+类Gorilla浮点压缩,8:1的压缩比是实测数据。
  3. 超级表(STable)抽象——既保留了每设备独立存储的优势,又提供了跨设备的聚合查询能力。
  4. 内置降采样——滚动窗口聚合不需要再写Flink作业。
  5. 极低运维成本——3节点集群即可支撑每天TB级写入,不像ClickHouse需要更多节点。

三、关系型存储的MySQL建模

设备元数据虽然数据量不大,但模型复杂度不低:

-- 产品定义(设备模板) CREATE TABLE product_definition ( id BIGINT PRIMARY KEY AUTO_INCREMENT, product_key VARCHAR(64) NOT NULL UNIQUE COMMENT '产品标识', product_name VARCHAR(128) NOT NULL, device_type ENUM('sensor','actuator','gateway','camera') NOT NULL, protocol_type ENUM('mqtt','coap','http','modbus','opcua') NOT NULL, data_format ENUM('json','cbor','binary','protobuf') NOT NULL DEFAULT 'json', -- TSL(Thing Specification Language) - 物模型定义 thing_model JSON NOT NULL COMMENT '属性/服务/事件定义', status TINYINT DEFAULT 1, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) COMMENT '产品定义表'; -- 设备实例 CREATE TABLE device_instance ( id BIGINT PRIMARY KEY AUTO_INCREMENT, device_id VARCHAR(64) NOT NULL UNIQUE COMMENT '设备唯一标识', device_name VARCHAR(128), product_id BIGINT NOT NULL, -- 设备密钥(一机一密) device_secret VARCHAR(128) NOT NULL, -- 激活状态 activation_status ENUM('inactive','active','disabled','deleted') DEFAULT 'inactive', first_online_time DATETIME, last_online_time DATETIME, -- 设备属性(冗余物模型中的关键字段,避免JSON解析) firmware_version VARCHAR(32), ip_address VARCHAR(45), rssi INT COMMENT '信号强度', -- 地理位置 location POINT SRID 4326 COMMENT 'GPS坐标', geo_hash VARCHAR(12) COMMENT 'GeoHash(用于空间查询)', -- 租户/分组 tenant_id BIGINT NOT NULL, group_id BIGINT, -- 标签(JSON,支持动态扩展) tags JSON, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_product (product_id), INDEX idx_tenant (tenant_id), INDEX idx_status (activation_status), SPATIAL INDEX idx_location (location), INDEX idx_geo_hash (geo_hash) ) COMMENT '设备实例表'; -- 设备关系(如:传感器属于某个网关) CREATE TABLE device_relation ( id BIGINT PRIMARY KEY AUTO_INCREMENT, parent_device_id VARCHAR(64) NOT NULL COMMENT '父设备(网关)', child_device_id VARCHAR(64) NOT NULL COMMENT '子设备(传感器)', relation_type ENUM('topology','group','shadow') NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_relation (parent_device_id, child_device_id, relation_type), INDEX idx_child (child_device_id) ) COMMENT '设备拓扑关系表';

四、冷热数据分层存储

这是控制成本的核心策略。不加以分层,时序数据的存储成本会随设备数量线性增长,2年内吃掉所有利润。

@Service public class TieredStorageManager { // 分层策略 private static final Duration HOT_RETENTION = Duration.ofDays(7); // TDengine保留7天 private static final Duration WARM_RETENTION = Duration.ofDays(90); // Parquet保留90天 // >90天自动归档到冷存储(S3 Glacier类型) /** * 每日执行的数据迁移 */ @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点 public void migrateData() { // 1. TDengine → Parquet(7天→90天) migrateHotToWarm(); // 2. Parquet → S3 Glacier(90天→永久) migrateWarmToCold(); // 3. 降采样:原始数据 → 聚合摘要 downsampleOldData(); } private void migrateHotToWarm() { // 从TDengine导出第8天数据,写入Parquet String sql = """ SELECT ts, device_id, temperature, humidity, vibration_rms FROM sensor_data WHERE ts >= NOW - 8d AND ts < NOW - 7d """; // 按设备ID分区写入Parquet,每个文件10000行 try (ResultSet rs = tdengineQuery(sql)) { ParquetWriter writer = new ParquetWriter( "/data/warm/date=" + LocalDate.now().minusDays(8) + "/", CompressionCodecName.ZSTD // ZSTD压缩比最好 ); List<SensorRecord> batch = new ArrayList<>(10000); while (rs.next()) { batch.add(mapToRecord(rs)); if (batch.size() >= 10000) { writer.writeBatch(batch); batch.clear(); } } writer.close(); } // 迁移完成后删除TDengine热数据(TDengine RETENTION自动处理) } /** * 降采样策略 * 原始数据10s采样 → 1分钟聚合 → 1小时聚合 → 1天聚合 */ private void downsampleOldData() { // 30天以上数据:从1分钟聚合到1小时粒度 downsampleService.aggregate( sourceTable = "sensor_data_1m", targetTable = "sensor_data_1h", windowDuration = Duration.ofHours(1), aggregations = List.of("AVG", "MIN", "MAX", "STDDEV"), startDate = LocalDate.now().minusDays(90), endDate = LocalDate.now().minusDays(30) ); } }

4.1 查询路由

查询层需要感知数据在哪一层:

@Service public class QueryRouter { public QueryResult query(QueryRequest request) { Instant queryStart = request.getStartTime(); if (queryStart.isAfter(Instant.now().minus(HOT_RETENTION))) { // 全部在热存储:直接查TDengine return tdengineQuery(request); } else if (queryStart.isAfter(Instant.now().minus(WARM_RETENTION))) { // 跨热温存储:并行查询,结果合并 CompletableFuture<QueryResult> hotFuture = CompletableFuture.supplyAsync(() -> tdengineQuery(request.restrictTo(HOT_RETENTION))); CompletableFuture<QueryResult> warmFuture = CompletableFuture.supplyAsync(() -> parquetQuery(request.before(HOT_RETENTION))); return hotFuture.thenCombine(warmFuture, QueryResult::merge).join(); } else { // 涉及冷存储:返回降采样数据 + 提示 QueryResult result = parquetQuery(request); result.setNote("查询范围超过90天,返回降采样数据(1小时粒度)"); return result; } } }

五、总结

物联网数据存储架构的选型核心是"分层"——按数据特性分层、按冷热分层、按粒度分层:

  1. 时序数据和元数据必须分离存储。时序数据库(TDengine)处理高频写入和时间范围聚合,MySQL处理设备关系和属性查询。混用MySQL的结果就是写入瓶颈和查询超时。

  2. TDengine在当前是物联网时序场景的最优解——8:1的压缩比、"一个设备一张表"的物理模型、毫秒级的单设备查询,这三个指标直接决定了系统的可行性和运营成本。

  3. 冷热分层不是可选的优化手段,而是架构设计的必选项。7天热数据(TDengine)+ 90天温数据(Parquet)+ 永久冷数据(S3 Glacier)+ 多级降采样,这套策略让我们的存储成本控制在每月1.2万元,而全量存TDengine的成本是8.6万元。

数据的价值与查询频率正相关,与存储成本负相关——分层的本质是让每一条数据待在它应该在的位置。

http://www.jsqmd.com/news/1258257/

相关文章:

  • 光流法在低帧率视频目标追踪中的优化实践
  • Win10声卡驱动故障排查与重装全指南
  • 重磅!蓝卓入选工信部2025年新一代信息技术融合应用典型案例名单
  • MyBatis(上)
  • AI内容降重实战:从37%到8%的优化方法论
  • 2026达州漏水检测维修本地口碑榜TOP5权威推荐-专业仪器精准测漏-正规防水补漏公司推荐:卫生间/厨房/屋顶/阳台/外墙渗漏水检测师傅上门 - 安佳防水
  • 如何高效录制抖音直播:专业工具完整使用教程
  • 2026许昌漏水检测维修本地口碑榜TOP5权威推荐-专业仪器精准测漏-正规防水补漏公司推荐:卫生间/厨房/屋顶/阳台/外墙渗漏水检测师傅上门 - 安佳防水
  • 解锁AMD锐龙处理器隐藏潜力:SMUDebugTool硬件级调试完全指南
  • 许昌本地防水补漏精选TOP5推荐:正规漏水检测维修公司上门师傅推荐:厕所/棚顶/屋面/飘窗/阳台/地下室/厨房渗漏水精准测漏维修(2026最新) - 即刻修防水
  • 如何用5步快速掌握D2NN全光神经网络:光速AI推理的终极指南
  • 全栈独立产品数据库选型复盘:PostgreSQL 还是 MongoDB
  • 帮我在书本上画出了回忆中的学校-提示词
  • YOLO在GUI元素检测中的应用与优化
  • HarmonyOS 6.1.1 智能字幕、卡证识别与信息助手怎么设计?
  • GitHub Copilot Pro、Tabnine Enterprise、CodeWhisperer商业版性能解密(内部Benchmark泄露版):仅剩72小时可获取完整测试报告
  • 如何在单台电脑上实现分屏多人游戏:Nucleus Co-op 完全配置指南
  • Windows虚拟化环境安全与性能优化指南
  • 社交场景话题生成算法设计与实践
  • 用AI做治愈系音乐号
  • Linux系统服务管理:从System V init到systemd的演进与实战
  • 网卡驱动相关知识及移植
  • AI角色设计:从文字描述到精准视觉生成的技术解析
  • 北京电脑死机蓝屏数据丢失怎么办?2026年电脑维修推荐来了 - 本地品牌推荐
  • AI艺术生成可靠性评估:从理论到实践
  • 上海周浦中小学英语培训深度分析|家长常见痛点、孩子英语优势、机构正确选择方法
  • Transformer训练中的损失平台期与突发学习现象解析
  • 如何快速掌握网盘直链下载助手:新手完整指南
  • Vue3网易云音乐项目实战:从组合式API到性能优化完整指南
  • Figma中文汉化终极指南:设计师必备的免费开源工具