在过去的一年半里,我和我的团队一直在尝试预测公共道路上公共汽车的运动,并预测它们在公共汽车站的到达和离开时间。我们的客户是一家名为 Kolumbus 的公共交通公司,它已在许多车辆中安装了物联网 (IoT) 网关,这些车辆每秒都向 Microsoft Azure 云发送消息。
虽然我们的大部分数据都是地理空间数据,但问题本质上是时间问题。研究它让我思考了时间的概念以及它与实时系统的各个部分之间的关系。
86,400。这是一天中的秒数,这个数字解释了为什么物联网已成为大数据时代的典型代表。
一个传感器通常每天只能记录那么多信息。根据有效负载的大小,总计可能有 5 MB 的数据。虽然这听起来可能并不多——它是一个略大的 mp3 文件的大小——但物联网解决方案很少只是一个传感器。嵌入式设备通常会连接多个传感器,然后将它们连接到路由来自多个设备的流量的网关。再加上一个典型的流处理管道通过几个步骤咀嚼、处理和丰富原始有效负载的事实,我们手头上有一些重要的数据。
物联网设备产生大量数据,机器学习需要大量处理。当你将它们放在同一个句子中时,通常不会首先想到“轻量级”这个词。现在你可能想知道为什么这三个都出现在本文的标题中。我们会解决的。
支持 IP 的物联网设备或网关使用 MQTT 或 AMQP 等通信协议将遥测数据发送到公共云中的中央消息代理。代理可以是云原生服务,例如Azure IoT Hub 或 AWS Kinesis,或者像 Apache Kafka 或 Flink 这样的开源框架。这些技术可以以合理的成本从数百万台设备中获取消息,这意味着我们可以可靠地收集所有传感器数据。到现在为止还挺好。
对数据采取行动并产生可操作见解的愿望不可避免地导致以下问题:
怎么办?
那时组织通常会聘请像我这样的顾问。
顾问经常会提出这样的建议:
流处理器订阅来自代理的消息并动态地对它们进行反应性处理,立即将其提供给丰富数据的实时视图。在记录原始消息的几百毫秒内,结果可在实时视图中获得,并可显示在报告仪表板中。机器学习 Web 服务连接到流处理器并执行预测分析,成为实时输出的一部分。这被称为“从消防软管中喝水”,是在流处理平台中使用机器学习模型的规范方式。它是这些类型系统的主要标准架构的核心:所谓的 Lambda 和 Kappa 架构。
在设计实时系统时,我们应该问自己的第一个问题是它如何适应项目的特定约束和要求。将机器学习模型直接连接到流意味着每个 IoT 消息的请求都将发送到预测端点。这可能意味着服务器集群和可观的托管费用。当速度和数量增加时,成本、复杂性和延迟也会增加。
虽然在某些情况下可能需要从消防水管中喝水,但喝一杯水通常更舒服。
在设计软件时,我们有时会谈论“近实时”。这里的“接近”暗示了这样一个事实,即我们永远无法在任何系统中实现零延迟。在系统响应之前,不可避免地会经过一些非零处理时间。当它非常快时,我们会作弊并将其称为实时。但是我们在哪里划界呢?100 毫秒?一秒?一分钟?
在我们考虑是否可以实现适当的实时或接近实时之前,我们应该考虑实时要求,这完全是另一个区别。我们应该问自己一个更基本的问题,而不是简单地考虑技术上的可能性:反应缓慢的后果是什么?
实时需求分为三类:
面对现实吧。很少有系统实际上有严格的实时要求。但即使是严格的实时要求也很少见。大多数系统都有相当宽松的时间限制。
回到我们的公交车预测,这是一个具有软实时要求的系统的经典案例。如果我们在 8:30 预测一辆公共汽车将在 9:00 到达某个站点,那么该预测在几秒钟后仍然有效并且几乎同样准确。即使在 8:31 或 8:32,预计到达时间 (ETA) 也不会发生根本性变化。
对于软实时性要求,我们可以选择对数据进行下采样。毕竟,传感器信号的频率只是我们用来从设备中采样的任意时间段。我们不需要处理每条传入的消息,这不是给定的。
这个简单的功能称为翻转窗口,所有主要流处理框架都支持开箱即用。通过查看固定大小的时间窗口,我们可以以某种方式聚合数据或仅处理批处理中的最新消息。
在后一种情况下,我们只对捕获传感器的最新状态感兴趣。当你想到它时,这就是物联网设备已经在做的事情,只是速度更快。
这允许稍微不同的架构。
在此设置中,计划任务(例如 cron 作业)以特定时间间隔唤醒,查看流管道的最新输出,生成预测并再次进入睡眠状态。在我们等待任务再次触发时,旧的预测仍然有效。请记住,鉴于我们的软实时要求,预测在有限的时间内将是有价值的。
这可能并不适用于所有场景,但在适用时,它可以大大降低系统成本。借助现代云服务,我们通常不会为闲置的处理单元付费。
另一个很好的方面是我们将预测分析与我们希望对每条消息执行的更简单的处理形式分离。
作为旁注,我们也可以将一些相同的理念应用于模型训练。在大型数据集上训练模型时,下采样是一种经常被低估的策略。
在我们的实时总线系统中,我们将预测和训练功能从流传输层中分离出来,并将它们放入单独的 Docker 容器中,这些容器在需要时会启动。
这样,我们就拥有了一个独立的基础架构,只要流管道接收到 IoT 消息,就可以在新数据上保持训练模型并生成实时预测。
该系统的这一部分目前每天处理几百万条消息,每月花费大约 60 美元。这包括托管、计算和存储。我们通过利用容器即服务 (CaaS) 和功能即服务 (FaaS)(也称为无服务器)的云范式来实现这一目标。
目前,我们在一个具有单 CPU 内核和 2.5 GB 内存的小型 Docker 容器上运行预测任务,它的响应速度仍然相对较快。这没有太多优化。事实上,我们正在并行运行一些不同的机器学习模型来评估它们在生产中的性能,所有这些都在一个容器实例上。限制流向端点的流量允许我们采取这些自由。
推理很便宜。那么训练呢?
训练模型需要更强大的服务器,但我们仍在运行具有四个 CPU 内核和 5 GB 内存的相对适中的实例。我们对数据进行了相当多的下采样,每天只运行几分钟的工作。通过这样做,我们将这项特定任务的成本保持在每月 2 美元的低得离谱的水平。
我们预计到系统的入站物联网流量至少会增加一个数量级,但负载测试的结果表明我们的设置可以相对轻松地处理它。训练容器可能需要更多的马力,但鉴于它只运行一小部分时间,即使我们使用 Kubernetes 等集群技术扩展到多个节点,它仍然很便宜。
我上面描述的内容并不适用于所有问题。在某些情况下,你需要按顺序预测每个事件。但在物联网场景中,通常情况下可以跳过时间步骤。事实上,平滑信号甚至可以帮助防止模型过度拟合。
我们的系统以极低的成本在最小的基础架构上运行,同时满足我们的性能要求。我们已经在 Azure 上部署了这个,但我故意避免为我们的组件使用营销名称,因为这个概念和通用架构可以在任何通用云平台上实现。
我的意思不是建议我们的架构作为每个人都遵循的标准。这只是呼吁数据科学家和数据工程师在设计过于复杂和繁重的系统之前考虑其机器学习管道中每个单独组件的时间限制和实时要求。
原文链接:轻量级IoT机器学习架构 — BimAnt