物联网海量数据湖分析架构(推荐实践)
┌──────────────┐
│ IoT设备端 │
└──────┬───────┘
│(MQTT/HTTP)
▼
┌──────────────┐
│ EMQX等 │ 可选(也可设备直接接Kafka/MQ)
└──────┬───────┘
│(MQTT→Kafka Bridge)
▼
┌──────────────┐
│ Kafka │ ★ 数据总线,高并发缓冲与削峰
└──────┬───────┘
│
│(流式消费)
▼
┌────────────────────────┐
│ Flink/Spark Streaming │ ★ 流/批处理,数据清洗、聚合、分桶分区、批量落盘
│ (写数据湖/OSS) │
└──────┬───────────┬─────┘
│ │
│ │
│(7天内热数据) │(数据湖分区归档)
▼ ▼
┌──────────────┐ ┌────────────────────────────┐
│ MongoDB │ │ OSS/S3/MinIO 数据湖区 │
│(短期热数据)│ │ Parquet/ORC分区批量归档存储│
└──────────────┘ │(如year=2025/month=05/…) │
└────────────┬───────────────┘
│
┌───────────────┴──────────────┐
▼ ▼
Trino/Presto/StarRocks 离线分析/可视化
★ 分布式SQL分析引擎
直接查OSS湖区(支持中位数、P95、聚合统计)
架构分层说明与选型理由
1. 采集层
- IoT设备端 → EMQX(可选)→ Kafka
- 负责承接海量并发,Kafka做主消息缓冲和削峰,方便后端弹性扩容。
2. 计算与写入层
- Flink/Spark Streaming
- 实时消费Kafka消息,数据预处理、格式校验、异常数据隔离。
- 批量写入MongoDB(仅7天热数据)用于短期API查询。
- 按时间/设备等分区批量归档到OSS/数据湖(Parquet/ORC格式),实现低成本无限扩容。
3. 存储层
MongoDB
- 只保存近7天热数据,满足实时接口和最新查询需求。
- 定期自动清理过期数据,降低成本。
OSS/S3/MinIO(数据湖区)
- 主存储,Parquet/ORC分区存储全部历史数据,适用于大批量聚合分析。
- 按时间、设备等多级分区,检索效率高。
4. 分析与服务层
Trino/Presto/StarRocks
- 直接用SQL连接OSS数据湖,支持max/min/avg/median/p95/窗口聚合等分析。
- 支持多用户高并发大规模历史数据查询,完全无需再将OSS数据批量倒回MongoDB。
可选:离线分析/BI可视化工具
- 如Superset、Tableau,连接Trino等实现数据报表和大屏。
核心优势
- 超强弹性:Kafka、Flink、OSS/数据湖全部可横向扩容。
- 冷热分层、成本低:MongoDB只做热数据,OSS承担所有归档数据,节省高性能数据库资源。
- 超强分析能力:Trino/Presto等支持SQL直查海量历史,聚合/分位点分析性能极佳,毫无压力。
- 开发和运维简单:如同MyBatis查MySQL一样用SQL查数据湖,逻辑简单,技术栈成熟。
数据湖分区和存储规范举例
存储格式:Parquet(列式存储,压缩高效,分析性能好)
分区策略:
oss://iot-data-bucket/iot_data/year=2025/month=05/day=20/device_id=xxxx/part-xxxxx.parquet
或简单时间分区+字段过滤
每条数据内容:
device_id ts param_a param_b … xxx001 2025-05-20 10:01:23 12.3 8.6 … xxx002 2025-05-20 10:01:24 15.4 7.8 …
查询范例(以Trino为例)
SELECT
date_trunc('minute', ts) AS minute,
avg(param_x) AS avg_value,
max(param_x) AS max_value,
min(param_x) AS min_value,
approx_percentile(param_x, 0.5) AS median_value,
approx_percentile(param_x, 0.95) AS p95_value
FROM
hive.iot_data
WHERE
device_id = 'your_device_id'
AND ts BETWEEN TIMESTAMP '2025-05-19 00:00:00'
AND TIMESTAMP '2025-05-19 23:59:59'
GROUP BY
date_trunc('minute', ts)
ORDER BY
minute;
常见问题解答
OSS数据能实时查吗?
通常数据归档延迟可做到分钟级,Trino等SQL引擎查OSS/MinIO的数据几乎是实时的,性能远超传统数据库聚合。Java应用如何查?
和查MySQL一样,用Trino/Presto的JDBC驱动发SQL即可,不需要自研复杂代码。如果业务刚迁移,原有MongoDB接口怎么办?
前7天热数据照常查MongoDB,历史分析走SQL数据湖即可,两者可并行平滑过渡。
补充:核心技术选型
场景 | 推荐组件 |
---|---|
消息中间件 | Kafka |
流式处理 | Flink/Spark Streaming |
热数据缓存 | MongoDB |
数据湖/归档存储 | OSS/S3/MinIO + Parquet |
SQL分析 | Trino/Presto/StarRocks |
BI与报表 | Superset/Tableau等 |