ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

物联网存算分离架构实践:海量数据冷热分层与实时计算

物联网存算分离架构实践:海量数据冷热分层与实时计算 1. 物联网数据到底有多大脾气为什么传统架构先撑不住了我最早接触物联网数据平台是在一套食用菌栽培车间的环境监控系统里。当时车间里只装了四五十个传感器节点用的方案很朴素——设备通过MQTT上报温湿度、二氧化碳浓度、光照强度后端服务收到数据后直接写进MySQL展示页面再实时查询。系统跑了大半年数据量也就几个GB一切都还说得过去。后来车间扩建设备从几十台涨到一千多台采集频率也从每分钟一次调高到每五秒一次。差不多两周之后问题集体爆发写入变慢、报表查询卡死、磁盘占用肉眼可见地往上跳。最头疼的是我只是想查上个月某个车间的平均温度曲线一条本来不需要多复杂的SQL硬生生跑了三十多秒。也是从那个时候起我开始认真琢磨存算分离这件事。先别急着上架构我们得先把物联网数据的特征聊透。存算分离不是银弹它能解决问题恰恰是因为物联网数据的几个脾气和传统业务数据完全不同。1.1 时序且只增不减写入量是爆发式的物联网数据有一个非常鲜明的特征它是时间序列数据只追加、不修改、极少删除。一个传感器节点每5秒上报一条记录一天就是17280条如果车间里有2000个这样的节点一天就是3456万条。一个月就是上亿条。而且这种数据是持续不断的没有所谓的业务高峰低谷——生产过程不停数据就不停。这种写入模型和传统电商订单、用户账户完全不同。订单数据虽然也增长但至少业务有时间窗口可以低峰批处理物联网数据却是完全平稳的洪流你根本没有喘口气的机会。传统关系数据库在处理这种持续高强度的写入时索引维护、行锁竞争、磁盘随机IO都会成为瓶颈这还没算上后续的备份和清理压力。1.2 冷热梯度极度分明去年今天的数据基本没人查物联网数据的第二个特点是访问频率随数据年龄急剧衰减。实时监控、设备告警、当日日报查的都是最近几小时到几天内的数据这部分是热数据一周前的数据偶尔被数据分析师拉出来做趋势对比算温数据三个月以上的历史数据除非做季节性分析或故障溯源否则基本处于沉睡状态是冷数据。传统架构的问题在于不管你存到MySQL还是本机文件冷热数据都是混在一起的。你为热数据准备了SSD和内存缓存冷数据也跟着享受同等待遇但它们的查询频率可能差了上千倍。存储成本白白浪费且数据量越大这种浪费越刺眼。1.3 设备异构、时间乱序、质量参差不齐做过物联网接入的朋友应该都懂真正让人掉头发的往往是数据质量本身。同一套系统里可能有国产温湿度探头、进口CO2传感器、自制单片机采集模块它们的上报协议不一样、精度不一样、时间基准也不一样。网络抖动会导致数据延迟到达——设备端时间戳是10:00:03的包可能10:05才到服务器这就是典型的乱序数据。还有的设备掉线后重新上线会重传一大堆历史缓存数据瞬时打爆消息通道。这些特征决定了物联网数据平台不能简单地把数据入库了事它必须能容忍乱序、识别迟到数据、做去重和质量清洗。而这些对存储与计算架构的弹性、吞吐能力提出了很高的要求。传统单机数据库 应用服务器的组合在数据量小的时候够用数据量一上来就处处掣肘。这个时候存算分离的理念就成了一个值得认真对待的答案。2. 存算分离不是数据上云这么简单一次架构演进的真实动机2.1 为什么存储和计算绑在一起是浪费的根源传统的单体架构里存储和计算是强耦合的。你的MySQL跑在一台物理机或虚拟机里数据落在本地磁盘计算也在这台机器上执行。这台机器的CPU、内存、磁盘必须同时满足两种需求既要能扛住实时的写入和查询又要能装下不断膨胀的历史数据。问题来了你为了数据容量买了一台大磁盘的机器但CPU核数不多缓存命中率一高就CPU飙红你为了查询性能买大内存的机器但磁盘空间很快就不够用了。因为计算和存储无法独立扩展最后只能频繁地做垂直扩容花钱不说扩容时的停机迁移也是一场灾难。存算分离的核心思想其实很简单把数据放在哪和数据怎么算彻底拆开。存储层用独立的大容量、低成本存储系统对象存储或分布式文件系统计算层则是无状态的弹性资源池需要跑分析时就拉起一批计算节点跑完就释放。谁也不拖累谁。2.2 物联网场景为什么尤其适合吃这一套存算分离不是新概念数据仓库领域早就这么干了比如Snowflake。它之所以在物联网场景里格外契合是因为物联网的工作负载天然是写多读少、写常读稀。写入端每天几亿条设备数据持续涌入存储层必须能无限平滑扩展扩容过程还不能影响写入。对象存储这类系统天生就能扛这种规模业务方完全不用关心容量上限。计算端真正需要计算分析的时刻是离散的。比如每天早上8点跑全厂生产日报、每个月1号跑能耗趋势分析、突发事故时临时做一小时维度的全链路排查。这几类计算任务的资源需求可以相差十倍以上。如果按峰值规格常备计算集群平时就是在浪费电。而存算分离之后计算资源可以秒级拉起、用完释放钱的消耗和实际算力消耗才真正对得上。2.3 存储成本是最后的临门一脚价格因素也得算一笔账。传统本地磁盘或云硬盘的单价往往比对象存储贵好几倍。物联网历史数据动辄几十TB甚至PB级如果全部放在高性能块存储上每年的存储成本就是个不小的数字。而存算分离架构可以非常自然地把冷热数据分开放近期数据放在高性能存储供实时查询历史归档数据直接转存到对象存储成本能降一个量级。这个优势在数据量大的项目上会直接决定项目能不能长期可持续地运转下去。3. 一个可落地的存算分离物联网数据平台怎么搭组件选型与数据流转概念说完了落到实操层面才是最见真章的地方。存算分离物联网平台没有标准答案但有一个经过大量项目验证的通用骨架。我基于自己的项目经验把组件选型和数据流转梳理成了一条清晰的链路。3.1 核心组件选型写到这里字可以先省下来在设计核心组件的时候我会提醒自己记住物联网数据的特点海量写入、时序特征、冷热分层、偶发批量计算。我给出一个我实际用过的组合这套组合兼顾了成本、可靠性和团队上手难度。层次推荐组件为什么选它接入层EMQXMQTT Brocker支持百万级连接内置规则引擎便于做数据预处理消息缓冲Kafka吞吐量极高数据持久化可靠生态系统成熟小团队也可以用Pulsar替代实时计算Flink对流处理、窗口计算、乱序支持最完善和Kafka配合成熟分层存储MinIO私有化部署或云对象存储容量弹性扩展单价低存放Parquet格式历史数据高频查询Doris 或 ClickHouse对海量时序数据的聚合查询能力极强支持实时写入和秒级响应元数据管理Hive Metastore 或 自研元数据服务让查询引擎能看见对象存储里的结构化数据这套选型的核心思路是实时链路用 Flink 做数据处理出结果后近期的热数据落到 Doris/ClickHouse 供大屏和实时告警查同时按时间分区将原始数据以 Parquet 格式定期归档到对象存储冷数据的分析查询则由 Doris 的冷查询能力或 Trino 直接从对象存储扫描。这里分享一个选型心得不要一上来就追求一套组件解决所有问题。物联网项目初期用 Kafka Doris 对象存储就能解决90%的问题Flink 可以在你明确有实时计算需求时再引入。组件越多运维压力越大尤其小团队谨慎为上。3.2 数据链路全景一条完整的管道是怎么跑的我把这条链路拆成五个环节大家对照自己的项目就能发现缺口在哪里。第一个环节是设备接入。各种传感器通过MQTT协议连接到接入层网关这里需要做设备认证、Topic权限控制。我的经验是设备端上报的原始消息不要直接在接入层做复杂处理只做格式统一比如统一字段名、统一时间戳格式然后就近写入消息队列。第二个环节是消息缓冲。Kafka在这里起到削峰填谷的作用。物联网数据虽然有固定的产生速率但设备批量重连、缓存补报会造成瞬时流量尖峰。Kafka在磁盘上持久化消息消费者按自己的能力拉取消费这保证了写入端永远不会被突发流量打垮。第三个环节是实时处理。Flink从Kafka消费数据做清洗和规整剔除明显超出传感器量程的异常值、对同一设备的重复上报去重、将不同设备的时间戳统一为毫秒级。经过处理的数据兵分两路路由到Doris/ClickHouse的实时表供在线查询使用同时以原始事件流形态写入对象存储的缓冲目录等待周期性归档。第四个环节是冷热分层存储。定期任务比如每小时或每天将对象存储里的增量Parquet文件做分区合并并注册到元数据服务。查询热数据走Doris查询冷数据走Trino直接扫对象存储。这个分层配合查询引擎的热表 外部表能力用户完全感知不到底层数据放哪儿了。第五个环节是应用访问。上层的可视化大屏、监控告警、数据分析平台都只面对统一的查询接口。固化报表直连Doris临时分析用Trino或Spark不同场景有自己的通道互不干扰。3.3 存储层的小技巧用分区策略控制查询成本冷热分离落到存储层时最重要的优化就是分区策略。我强烈建议按日期天分区并且在Parquet文件内部再按设备ID做排序或哈希分桶。这样做的好处是按时间范围查询时会走分区裁剪快速跳过无关数据过滤特定设备时谓词下推可以大幅减少扫盘量。别小看这些细节同一套存储上分区设计合理的表查询耗时可能比分区混乱的表少一个量级。4. 案例实操从食用菌车间监控说起看端到端融合怎么实现为了让大家能更直观地理解我拿开头提到的食用菌栽培车间物联网环境智能监控系统为例完整走一遍存算分离改造后的数据流程。这个例子的价值在于它的规模适中既能体现物联网架构的典型问题又不会因为数据量太夸张而让读者觉得离自己太远。4.1 需求拆解首先搞清楚系统到底被要求干什么食用菌栽培的核心是环境控制不同生长阶段菌丝培养、出菇管理对温度、湿度、二氧化碳浓度、光照有严格区间要求。监控系统的目标不是看看数据而是保障环境始终在合适区间并追溯每次环境异常的原因。具体拆解下来有三块任务第一实时监控与告警。车间内温湿度、CO2、光照等数据每5秒上报一次系统要在数值超过阈值时立即推送告警给值班人员并提供前后变化曲线。第二历史数据分析。技术员要能对比不同批次的生长曲线找出为什么这批菇的长势不如上一批的原因。这类查询往往跨度数周甚至数月而且要对多个传感器做聚合对比。第三设备联动控制。当CO2浓度偏高时系统要自动开启新风系统温湿度偏离目标区间时联动加湿器或者加热设备。这部分涉及指令下发和执行反馈。这三块任务对架构的要求完全不同第一块要低延迟第二块要能跑大规模扫描聚合第三块要可靠的服务端到设备端指令通道。把这三者揉在一个传统单体里就是最初系统崩溃的根源。4.2 数据分层实时、近线、归档各归其位改造后的系统把数据分成了三个层次。最前端的实时层保留最近24小时的明细数据放在Doris里每条数据约200字节2000个节点、5秒周期一天的明细量在6900多万条压缩后占用大约14GB。这个量级Doris完全可以轻松承受实时告警和当日曲线查询都能在百毫秒内返回。近线层保留最近1个月的聚合数据。系统在Flink里做了多级聚合按5分钟聚合的设备均值、按1小时聚合的车间均值这两类聚合减少了90%以上的数据量。技术员做常规趋势对比时直接查聚合数据不需要碰明细。归档层则是全部原始明细。Flink会把原始数据连续写入对象存储按天分区保存下来作为Parquet原始文件。为了压缩成本超过21天的明细会从Doris中自动清理归档数据便成为唯一的长期数据来源。历史分析查询通过Trino来访问对象存储里的这部分数据如果是跨月的全量分析系统内部会自动将任务提交给Spark SQL执行。好在这一层的数据量总体可控一台8核32GB的Trino节点就已经能支撑日常分析需求了。4.3 端侧联动触摸屏与云平台的双通道控制热词里频繁提及昆仑触摸屏物联网加用户我多聊一句端侧联动的实现逻辑。现场的值班室会有一块昆仑通态触摸屏它既是本地监控面板也是一个本地控制入口。车间内部的设备联动控制比如打开新风、启动加湿如果完全依赖云端转发一旦网络抖动就会导致控制不及时这在食用菌培养环节可能是致命的。所以我在这类项目里的做法是本地优先、云上兜底触摸屏通过本地PLC直接下发控制指令不依赖云端的网络路径同时触摸屏和PLC也会把操作记录和状态变化上报到物联网平台这些事件流一样进入Kafka和存储层作为后续追溯的数据来源。云端分析发现环境异常时再通过物联网平台的反向指令通道向下推送远程控制指令到网关由网关现场执行。这算是存算分离体系里边缘控制和云端分析的一次明确分工。4.4 这套架构带来的实际可量化的改善改造完成之后我记录了几个关键数据MySQL方案下写满1亿条后单次报表查询平均耗时20秒左右切换到新架构后24小时实时明细查询约为300毫秒跨月趋势分析约3~5秒归档数据全量扫描加聚合的耗时则取决于查询的月份跨度。存储成本上对象存储相比原先的高性能云硬盘每TB单价低了近80%Doris节点则是按需扩容的平时只保留3个节点跑月报任务时临时扩到5个节点跑完就缩回去。实实在在的费用对比让当初还对这套方案有所疑虑的同事彻底闭了嘴。5. 融合落地时最容易踩的坑小文件、乱序、权限与成本存算分离物联网平台讲起来很美好真正落地的时候暗坑不少。我把自己趟过的坑整理成清单给大家做个参考。这些都是文档里不怎么会写、但实际项目中大概率绕不过去的问题。5.1 小文件问题海量设备生成的数据碎屑物联网数据落到对象存储里最典型的坑就是小文件。每个设备每5秒一条记录如果按设备ID分目录写Parquet一小时就会生成几千个小文件。小文件对对象存储本身没有影响但对查询引擎是灾难——Trino或Spark扫描数据时每个文件都会产生一次同步与调度开销几千个几KB的小文件会让查询耗时暴涨。解决思路有两个并且通常是配套使用。一是在Flink写入时做按时间窗口的攒批比如Sink在攒够100MB或1分钟窗口后才落盘一个Parquet文件这样文件大小比较均匀不至于太小二是跑周期性的合并任务每天晚上把一天的小文件合并成5到10个大Parquet文件顺便做一次基于设备ID的排序为白天的查询分析做好准备。两个思路结合实施后查询性能能获得质的提升。5.2 流式写入的乱序与迟到数据前面说过物联网数据天然有乱序问题。不少团队第一次搭实时链路时忽略了这个点结果出来的时候傻眼了Flink窗口计算出来的车间平均温度怎么看怎么不对。原因很简单——设备端时间戳和服务器处理时间之间可能有十几秒的偏移按处理时间开窗口会把一批数据切得七零八落。正确的做法是基于事件时间处理并配置延时窗口。在Flink的Watermark策略上我会允许最大10秒的乱序容忍度窗口等待策略设为迟到30秒内的数据重新触发计算并更新结果。这样设备端网络抖动造成的延迟就不会影响窗口聚合的正确性。5.3 权限与数据治理谁都能看到所有设备数据是要出事的存算分离带来的一个隐患是权限边界模糊。以前数据在MySQL里你给业务部门一个只读账号就行现在数据散落在对象存储、实时查询引擎、归档系统等多个地方如果每一处都独立授权很容易出现某个数据工程师能访问全厂所有数据的权限漏洞。我建议从一开始就建立一个统一的元数据中心把哪个项目组、哪些设备、哪些表、哪些目录的四元组关系管理起来。查询引擎和作业平台都从这里拿权限配置而不是各自跟自己本地的账号体系对接。这个工作虽然前期看起来多于但等到系统里接入第二个车间、第三方运维团队进场时你会庆幸当初做了这套基础设计。5.4 别把边缘和中心混为一谈最后一个是架构层面的提醒。存算分离不代表所有数据都必须先上云或进中心。在车间这类现场环境中边缘计算节点具备一定的本地数据处理能力可以承担一些轻量级实时分析和控制闭环。像食用菌车间很多基础告警判定放在边缘网关上就能完成不需要经过数据上传中心→中心分析→指令下发这条路径。存算分离解决的问题是海量历史数据的弹性存储与批量计算而不是所有计算都必须发生在中心。正确理解这两者的边界才不会为了架构上的美观牺牲掉实际业务的实时性。站点侧的实时判断做实了云端才能腾出资源做好全局优化本地与中心各自干自己最擅长的事这样融合才有意义。这套架构从落地到现在运行了一年多中间也经历了好几次小规模调整。最大的体会是存算分离不是一步到位的重构反而是逐步演进的结果。你可以在原有系统上先引入对象存储做冷数据归档再慢慢把热数据查询迁移到列式存储引擎最后等实时链路稳定之后再考虑用流式计算替代原有的批处理。每走一步都能看到明确收益团队也更容易接受变化。物联网平台的架构选型很多时候不需要追求最新奇的技术而是在合适的数据规模下选择性价比最高的组合并且为未来发展留下充足的扩展空间。
返回列表