《Architecting Data and Machine Learning Platforms》第八章:流处理的架构

在本章中,您将了解为什么行业趋势不可阻挡地从批处理转向流处理。我们将讨论不同的流处理架构以及如何在它们之间进行选择。我们还将深入探讨其中两种架构------微批处理和流处理管道,并讨论如何在这两种架构中支持实时的、自由的查询。最后,有时进行流处理的原因是在发生特定事件时自动执行某些操作,我们将讨论如何设计这样的自动化系统。

流处理的价值

企业在技术成熟度的整个范围内,从数字原生企业到更传统的公司,跨足多个行业,都认识到迅速做出决策的不断增加的价值。例如,考虑业务A,该业务需要三天才能批准一笔车辆贷款。另一方面,业务B将在几分钟内批准或拒绝贷款。这种增加的便利性将使业务B在竞争中具有优势。

比更快的决策更好的是能够在上下文中做出决策。能够在事件进行时做出决策(参见图8-1)比在几分钟后做出决策更有价值。例如,如果您能在提交信用卡进行付款时检测到欺诈行为并拒绝交易,您就可以避免昂贵的返还过程。

行业应用案例

无论是欺诈检测、交易结算、智能设备还是在线游戏,一个又一个行业开始采用流处理技术。 在医疗保健领域,我们看到流处理技术用于实时患者监测,对跌倒或自伤进行警报,利用物联网医疗设备提供个性化护理,以及在医院中优化药物、供应和库存。

在金融服务领域,我们看到流处理技术用于检测和防止欺诈、预测和分析风险,识别违反合规法规的交易,向客户提供个性化的优惠。 在零售业,我们看到流处理技术用于网站上的个性化营销,实时跟踪多渠道(网站、移动端、实体店)的库存情况,提醒履行问题,动态定价,产品推荐和全渠道客户可见性。

在媒体和娱乐领域,我们看到流处理技术用于生成个性化内容,传递定向广告,减少客户流失,并防止订阅欺诈。在电信领域,我们看到类似的客户流失和订阅欺诈用例。此外,流处理技术还用于提高网络可靠性和优化网络容量规划。

实时数据处理的使用案例

把实时数据处理看作是对无限数据集进行处理。从技术上讲,实时数据处理面临着双重挑战。一是数据集是无限的,永远不会完全完成。因此,所有的聚合(例如最大值)只能在时间窗口内定义。另一方面,数据正在流动并保存在临时存储中。这使得应用传统的编程技术和概念,比如文件句柄读取和处理数据,变得困难。由于这种复杂性,将实时数据处理用例分为四个类别,按复杂性和价值递增的顺序如下是非常有益的:

  1. 流数据摄取

    • 当你只关心跟上数据流并将其存储到持久性存储中时使用。
  2. 实时仪表盘

    • 在希望以数据流的形式可视化数据时很有用。您还可能对数据的时间窗口聚合的统计信息和图表感兴趣。
  3. 流分析

    • 当您希望对数据进行计算并在其到达时执行操作时使用。通常用于向人类操作员发出关于阈值超限或异常模式的警报。
  4. 持续智能

    • 对流分析的自动化,以便可以在没有任何人工干预的情况下执行操作。

在接下来的部分中,我们将深入探讨每种情况的架构。您会发现这种架构非常模块化,您可以通过构建简单的系统,并根据需要逐渐增加复杂性。并非必须构建最终、最复杂的自主系统才能从实时数据处理中获得价值。然而,这假设您在诸如Apache Beam之类的框架中进行数据处理,该框架将允许您无缝地从批处理切换到流处理。虽然Beam是由Google创建的其托管的Cloud Dataflow服务的API,但Apache Flink和Apache Spark都支持Beam。因此,您可以在其他超大规模计算提供商上运行Beam管道的托管Flink和Spark实现。这些类别是逐步构建的,因此第一个是所有四种用例的基础。为了做出更快的决策,您需要几乎实时地摄取数据,即事件发生时。这就是所谓的流数据摄取,我们将在接下来进行介绍。

流数据摄取

流数据摄取可以通过两种方式完成:

  1. 您可以聚合事件并仅将聚合数据(例如每小时平均值)写入持久存储。这被称为流式ETL,因为聚合是一种转换(ETL中的T),位于提取和加载到持久存储之间。
  2. 或者,您可以直接将数据摄取(加载)到数据湖或数据仓库,然后期望客户在分析时转换数据。这称为流式ELT。

让我们在以下子节中更详细地了解这两种方法。

流式ETL

如果您的目标是向业务提供更及时的数据,那么流式摄取就足够了。首先,您需要关注数据在云中的摄取位置,因为这非常重要。您需要将数据存储在一个可以访问以进行处理或查询的位置。对于查询,确保结果反映最新数据是很重要的。

因此,为了实现实时洞察的目标,摄取必须发生在允许实时摄取和查询的系统中。现代数据仓库,如Google BigQuery、AWS Redshift和Snowflake,具有这种能力。因此,通常您会执行流式ETL到这样的数据仓库中,如图8-2所示。

因此,流式ETL的目标通常是将数据落入数据仓库。从多个应用程序写入的日志数据由本地代理读取,该代理负责使日志数据可用于实时监控和查询。通过重新构造数据的内容并使用适当的本地代理,您可以将相同的架构调整为其他类型的实时数据,无论是来自物联网设备还是在线游戏。

本地代理可以通过以下两种方式之一使数据可用于实时查询(见图8-2):

  1. 微批处理:与过去5分钟的数据对应的数据被写入云blob存储上的文件。在云blob存储中出现新文件会触发加载函数(例如Google Cloud Functions,Google Cloud Run,AWS Lambda,Azure Functions等)。该函数可以处理数据,然后将文件加载到最终目标中。微批处理涉及一些延迟。
  2. 流水线处理:本地代理可以为每个日志事件发布一个事件对应的事件到消息队列(如Kafka)或主题(如Cloud Pub/Sub)。这些事件被推送到流水线(例如AWS Glue或Google Cloud Dataflow),该流水线处理事件并将其插入最终目标中。这使事件立即可供查询。

加载函数或流水线的作用是处理数据,使其对下游用户和应用程序更加可用。通常,您将利用数据处理来:

  • 将事件数据转换为DWH表所需的模式
  • 过滤事件记录,仅保留与操作DWH的业务单元相关的数据
  • 对事件中缺失的值进行插值或以其他方式填充(例如,您将使用最近有效的值)
  • 连接时间跨度的事件(例如,您将利用身份解析方法将事件连接到用户会话中,甚至跨会话连接)
  • 将事件聚合成更易消费的块,例如写出时间平均值(例如,过去一分钟的总页面访问量而不是每次页面访问)或每个会话值(例如,一条记录,指示会话中单击了哪些按钮而不是每次单击按钮时都有一个记录)
  • 使用其他来源丰富数据(例如,货币转换)
  • 对敏感字段进行掩码、加密或以其他方式进行保护 如果您不需要执行上述任何活动,并且加载函数仅是一个通过的操作,请考虑是否可以使用下一节中的流式ELT方法。

在利用微批处理方法时,了解延迟的来源是有帮助的。显而易见的罪魁祸首是我们示例中加载到DWH的数据可能是五分钟前的。但通常这不是大问题。如果5分钟的延迟不可接受,您可以将其降低到30秒。真正的问题是DWH加载作业是排队的,因此它们可能不会立即发生。检查您的DWH的SLA以了解这种延迟可能是多少。通常,这种加载延迟是许多用例中使流摄入微批处理不可接受的原因。然而,如果批次包含例如每日数据,而加载的1小时延迟是可以接受的,则这是一种有效的架构。

微批处理方法通常比流水线方法便宜。一些数据仓库(特别是Google BigQuery)有一个加载数据免费的定价层。即使在像Snowflake这样的数据仓库中,它们对加载和插入都收费,插入的费用更高并且需要更高的定价层。此外,您只在函数运行时支付加载的计算成本。特别是如果每天加载数据一次,微批处理的计算成本可能非常低。在AWS Glue和Cloud Dataflow中,自动缩放确实缩小了随着微批处理频率增加而产生的差距。

我们已经介绍了前面提到的两种方法中的第一种。现在让我们转向第二种:流式ELT。

流式ELT

之前学到的流ETL方法假设您可以预期数据的使用者将需要哪一类清理、聚合或丰富。毕竟,在将数据写入DWH之前,您正在转换原始数据。这可能是一种有损操作。随着数据的使用者数量增多,以及不可能预测不同使用者需要哪种转换,许多组织将其数据流水线从流ETL切换到流ELT。如果转换需要业务特定的知识,并且最好由业务用户而不是程序员执行,那么流ELT也比流ETL更合适。

在流ELT中(见图8-3),本地代理直接将原始数据加载或插入DWH。数据的使用者可以应用他们需要的任何转换。在某些情况下,您可以提供数据的逻辑或物化视图,以便数据使用者更方便地使用。

流ELT的一个显著缺点是写入DWH的数据量可能很大------在许多ELT流水线中,转换步骤会显著减少数据并仅将聚合数据写入DWH。因此,流ETL与ELT之间的选择在很大程度上是基于业务价值和云成本做出的决定。

出人意料的是,数据量越大,流ELT变得越具有成本竞争力。随着数据量的增加,更频繁地处理数据变得更有意义。为了理解原因,想象一下,一个企业正在基于其网站流量创建每日报告,这份报告需要两个小时才能创建。现在假设网站流量增长了4倍。现在,报告将需要八个小时才能创建。要如何回到两个小时呢?好在这是一个极易并行化的问题。因此,将工作自动缩放到机器数量的4倍。如果相反,我们考虑一种使报告更及时的方法呢?

对六小时的数据进行四次每天的计算统计。 将这六个小时的报告聚合以创建每日报告。 您现在可以每天更新一次"每日"报告。 报告中的数据现在只有六小时的时间。 这当然是微批处理的想法。这两种方法的计算成本几乎相同。然而,第二种方法减少了延迟,增加了频率,分散了负载,并更好地处理了突发情况。而且,组织可以获得更新更及时、不那么陈旧的报告,这几乎不需要额外的费用,却能为业务带来巨大的好处。数据量越大,将从六小时报告变为每小时更新、每分钟更新,甚至实时更新变得更有意义。一旦需要向多个使用者提供准实时的更新,流ELT就成为一个非常有吸引力的选择。

流式Insert

在图8-2和8-3中,我们假设需要一个本地代理,该代理将查看可用数据并将数据加载或插入到持久存储中。并非一定需要这个中间层------如果DWH提供了流式API,云原生应用程序可能会绕过本地代理,使用云客户库自行执行插入(参见图8-4)。

例如,在BigQuery中,流式插入涉及到一个REST API调用,可以使用Python完成。Snowpipe Streaming在Snowflake中提供了这个功能,但在Redshift中,你必须使用Kinesis中的一个传递性转换步骤。

一些消息系统(例如Google Pub/Sub)还提供了特定的订阅类型,可以在事件发生时将其加载到DWH中,因此应用程序只需将事件发布到消息主题或队列,就可以实时在DWH中查看这些事件。

从边缘设备(物联网)进行流式处理

在图8-2中,我们假设流式ETL中的事件将由自定义本地代理发布到通用消息队列,例如Kafka。

在物联网(IoT)的情况下,云服务提供商通常有更有针对性的解决方案(见图8-5)。Azure提供了用于边缘软件的IoT Devkit和用于远程云组件的IoT Hub。在AWS上,本地代理将使用具有预构建AWS IoT Greengrass组件的软件,而远程队列将由AWS IoT Core进行管理。在Google Cloud Platform上,边缘组件可能由Coral设备和TensorFlow Lite软件组成,而远程云组件可能是Clearblade IoT Core。

您可以使用提供的边缘软件开发工具包(SDK)和设备进行本地处理、数据管理、ML推断等。利用提供的远程云组件,您可以激活定制功能,例如设备管理,并可以透明地处理不稳定的网络、设备重新启动等情况。

无论使用哪个云提供商,边缘SDK都将支持标准协议,例如MQTT,以及专有协议。选择一个标准协议可以保留部署软件到不同云的能力,特别是在边缘设备的情况下,由于合作伙伴关系和收购,最终很常见需要支持来自其他云的设备或在不同云上处理软件。例如,在AWS上使用Greengrass时,您可能希望考虑使用MQTT代理Moquette以确保可移植性。

流式传输目标

在图 8-2 和 8-3 中,我们假设需要将流式数据传送到数据仓库以支持交互式查询。但这并非一定如此,有两个例外情况:非结构化数据和高吞吐量流。

如果你正在流式传输视频,那么可以忽略上述内容,使用专为视频设计的框架。在边缘,您的视频摄像机将支持实时流传输协议,例如实时流传输协议(Real-Time Streaming Protocol)或 WebRTC。使用这些协议将实时视频流发送到云端。在 Google Cloud 上,Cloud Video Intelligence 将从实时流传输协议转换为可解码的视频流,并将流写入云存储中的文件。在 AWS 上,Kinesis Video Streams 提供了与 AWS SageMaker 的类似集成,并将机器学习推断结果发布到 Kinesis Data Streams。类似地,Azure Video Indexer 允许您从视频中提取见解。

数据仓库(DWH)是用于持久存储和交互式的自由查询的通用解决方案。然而,对于高吞吐量和/或低延迟的情况,数据仓库并非是一个好的解决方案。DWH 流式插入支持的典型吞吐量约为每秒千兆字节的数量,典型延迟为几秒。如果要每秒传输数千兆字节的数据或需要毫秒级延迟,那么 DWH 就不是一个好的选择。此时应选择 Google Cloud 上的 Cloud Bigtable 或 AWS 上的 DynamoDB。当然,这些都是 NoSQL 数据库,因此您正在以 SQL 的方便性为实时传输和查询进行权衡。相反,如果您的规模或性能需求未达到这些水平,则 SQL 解决方案将在基础设施和所需技能方面更经济。

如果即时查询不是问题,或者如果您的架构纯粹是数据湖而不是数据湖屋(请参阅第 7 章),也可以将流式数据传输到云存储中的文件。例如,Apache Beam 可用于将非结构化或半结构化数据存储在 Google Cloud Storage 上。在这样做时,重要的是要决定如何分片文件 - 流处理框架将在文件达到一定大小后自动对文件进行分片,但这些分片基本上是基于时间戳的(因为记录正在被流式传输出去),这可能不适合您的需求。

实时仪表板

无论是存储聚合数据还是将实时数据导入DWH,您可能希望提供决策者查看数据流入过程中的能力。您可以通过实时仪表板实现这一点。

实时查询

仪表板工具定期查询云数据仓库,以了解已着陆的事件并更新其图形。这种架构要求仪表板将查询下推到云数据仓库(见图 8-6)。换句话说,所有查询都是"实时的"并反映了云数据仓库中的最新数据。

早期的方法,比如数据立方体和数据集市,涉及将仪表板使用的 DWH 数据的子集或聚合物材料化,这些方法已经不再必要。即使像 Tableau 这样的仪表板工具具有创建和维护数据摘要的功能,最好还是直接对 DWH 进行实时查询 --- 现代云数据仓库可以处理这一需求。

如果你的 DWH 提供了为仪表板定制的便利或性能功能(例如将数据集缓存到内存中、对查询进行有时限的缓存、优化以返回先前的查询结果(如果数据没有更改)等),你应该启用它们。例如,在 Google BigQuery 中,可以启用 BI Engine。在 AWS Redshift 中,使用密集计算节点,因为它们专为仪表板所需的更重的计算而设计。

物化一些视图

最好不要在仪表板工具中使用复杂的 SQL 查询代码。创建检索所需数据的视图,并让仪表板工具查询该视图。通过用户定义的 SQL 函数在视图之间重用查询逻辑。

如果发现某些视图经常被访问,可以将该视图转换为物化视图(见图 8-7)。这提供了由仪表板维护的数据库提取的性能优势,而无需处理组织中漂浮的数据集所带来的额外治理负担。

然而,不要过分追求优化:用 Knuth 的话说,过早进行优化仍然是许多问题的根本原因。最小化使用物化视图,让大多数查询实时发生。物化视图会增加存储成本,如果特定的提取很少显示,则会增加很多不必要的开销。

流式分析

在实施仪表板时,你可能需要超越仅仅显示数据的范畴。你可能需要显示基于自动提取的见解和预测的对决策者有用的警报。这被称为流式分析。你可以通过对每个事件或基于时间表的计算分析来确定是否需要警报。在事件到达时执行这项任务效果更好,为此,你将需要一个流水线。如果选择按时间表执行,微批处理就足够了。

流式分析在以下情况下非常有用:

  • 时间序列分析:用于跟踪资产、预测事件影响和进行预测性维护
  • 点击流分析:用于实时提供优惠、创建动态网站和优化客户旅程
  • 异常检测:用于预测设备故障、防止欺诈和监控系统健康

随着我们在本节的深入探讨,我们将分别查看这些情况。这些情况的架构可以作为你可能遇到的其他流式分析用例的模板 - 你将需要同时写入主题和仪表板,就像时间序列分析一样,使用回填管道,就像点击流分析一样,或者像异常检测一样使用多个时间窗口。

时间序列分析

流式分析最常见的应用是定期验证数据值或计算基于时间的平均值。 例如,假设一个实体资产(比如交付车辆)将其位置实时传输到云端,我们想要分析资产的位置,并在以下情况下发出警报:

  • 资产移出预定的地理区域
  • 资产在其所在位置的速度超过某个预定的限制

这个用例的架构如图8-8所示。

可以通过 ETL 管道将位置数据实时写入 DWH,该管道从事件流(Kafka、Pub/Sub 等)推送新的位置信息。流处理管道(使用 AWS Glue、Google Cloud Dataflow、Apache Flink 等技术实现)处理实时流,验证位置,并将警报写入特定的主题。然后,激活函数在将新事件发送到此主题时触发,负责通过电子邮件、短信等方式将警报发送给感兴趣的人员。 流处理器能够对传入的事件流应用时间窗口,计算诸如平均速度之类的统计数据。它还能够从数据库获取静态值(例如特定位置的速度限制)。因此,它还能够执行第二个计算并对其进行警报。

最佳做法是不仅将警报消息写入警报主题,还要写入 EDW。为了让用户对他们接收的警报有所掌控,最好不要让流处理管道直接发送电子邮件或短信。这种责任的分离还允许您构建仪表板,显示此类警报的频率,并允许用户探索警报并希望能够识别模式。

点击流分析

点击流是访问者在应用程序或网站中执行的事件序列(例如按钮点击、页面浏览等)。为了收集这些数据,组织会对其网站进行仪表化,使用户活动调用一个网络操作,进而最终进入 DWH。随着许多业务的在线化,组织有可能根据点击流洞察客户行为。

尽管可以编写定制的 JavaScript 代码进行此类仪表化,并在自定义流处理管道中收集和处理数据,但更常见的做法是使用诸如 Google Marketing Platform 或 Salesforce Marketing Cloud 等预构建工具。Google Marketing Platform 包括 Google Tag Manager,用于对网站进行仪表化,以及 Google Analytics,它收集此信息并提供一种将点击流数据导出到 Google BigQuery 的方式,从而可以将其传输到任何其他 DWH。您可以使用来自公司(如 Fivetran)的连接器,类似地将 Salesforce Marketing Cloud 中的数据导出到所需的 DWH。还要检查您的 SaaS 软件是否提供将其内部数据与 DWH 同步的功能。例如,Salesforce 为 Snowflake 和 BigQuery 提供了此功能。

一旦数据进入 DWH,您可以使用 SQL 进行分析。点击流数据用于 A/B 测试、跟踪物品流行度的变化以及识别销售阻力。通过适当编写的 SQL,您可以执行所有这些操作。然而,处理代码将处理以下情况:

  1. 通过自动化代理(如蜘蛛(搜索机器人)和寻找安全漏洞的不良行为者)进行的活动。
  2. 启动在一台设备上并在另一台设备上完成交易的客户。除非客户在两台设备上都登录,否则自动会话跟踪可能无法捕获此情况。总体而言,用户标识是一个挑战,因为只有很小一部分用户会登录。其他所有机制(cookie、设备 ID、IP 地址等)相当频繁失败,如果有更多数据,可以改进。利用所有通道上可用的所有数据来关联可能是同一用户的数据集合的方法被称为身份拼接。存储结果集的 lakehouse 称为客户数据平台(CDP)。

由于这些情况,即使使用了预构建的 CDP,如 Segment 或 Bloomreach,通常也会构建后处理的"回填"流处理管道来处理组织独特的情况(参见图 8-9)。此流处理管道可能能够更好地执行身份拼接、隐私聚合和机器人检测等任务,而不同于预构建工具提供的更通用代码。同时,管道可能能够根据组织内的其他数据源(例如有关客户、产品、价格、库存水平等的信息)丰富点击流数据。正是这些经过回填和后处理的数据,您可以用于进一步的分析。

如果使用点击流数据构建个性化或推荐系统,则还需要在客户访问网站时采取行动。这将属于连续智能用例,我们稍后在本章中会涵盖。

异常检测

异常检测涉及在数据到达时识别异常模式。在任何您拥有大量关于"正常"行为是什么样的数据的情况下,但很难编写关于异常活动是什么样的具体规则(因为不良行为者不断改变攻击机制或因为环境可能发生变化)时,异常检测可能非常有用。异常检测用于检测定价错误的物品(突然之间,某个物品的受欢迎程度急剧上升)、超负荷的设备、在线游戏中的机器人活动、安全威胁等。

许多组织用于识别病毒和其他网络安全威胁的主要技术是基于签名的模式。在基于签名的模式中,系统利用过去检测到的病毒的存储库对抗新的威胁。然而,使用这种技术很难检测到新的攻击,因为没有可用的模式或签名。当使用异常检测时,通常会对过去三天的数据进行聚类(参见图 8-10)。假定远离现有聚类的任何事件都可能是可疑的。这使环境能够适应(因为聚类仅在最近三天的数据上完成),并且允许您识别尚未传播太广泛的异常模式。

弹性流式处理

在接收和处理流式数据时,可能会遇到格式错误的数据或者不知道如何处理的意外数据值。 在批处理中,通常会简单地抛出异常,然后期望程序员找到逻辑错误,进行修复,然后重新运行批处理作业。然而,在流处理中,流水线需要继续运行。同时,你也不希望只是忽略错误。 因此,每个流分析作业都必须设置一个死信队列,用于存储无法处理的任何事件。你可以定期检查这些死信队列并(与批处理作业一样)修复逻辑错误。

修复逻辑错误后,你必须在不丢失任何数据的情况下更新当前运行的流水线。像 Cloud Dataflow 这样的工具提供了在原地更新运行中的流水线或排空事件队列并无缝将处理转移到新流水线的能力。

更新正在运行的流水线会保留在途数据并在新流水线中恢复处理。为此,它重用了旧流水线的持久存储,以用于更新后的流水线。因此,这两个流水线必须满足一定的兼容性要求。如果处于兼容性维护的情况下,应该遵循这种方法,因为你可以实现精确一次语义。事件将被处理一次(即旧的或新的),而聚合结果将是准确的。

如果流水线不兼容(也许是因为 bug 修复改变了步骤之间传输的数据),下一个最好的方法是在启动新流水线之前排空现有流水线。现有作业停止从其输入源中提取数据,并完成所有在途和缓冲数据的处理,导致触发器发出打开窗口的内容,并将新事件发送到新流水线。排空流水线对确保至少一次处理语义至关重要,虽然不如精确一次好,但比简单取消运行中的流水线并丢弃数据要好。

通过机器学习实现的持续智能

无需人工参与决策。随着数据量的增长,将系统转变为人在回路中的模式变得非常普遍。在这种情况下,操作会根据实时洞察、警报和预测自动执行。人类监督员可以覆盖本应自动应用的操作,但系统被设计为能够在没有任何人工干预的情况下自主运行。这被称为持续智能。 为了使系统能够自主运行,您需要自动化以下过程:

  1. 使用历史数据对机器学习模型进行训练,如果需要,可以在随后的数据上对模型进行重新训练。
  2. 当事件发生时调用训练过的机器学习模型进行推断。
  3. 根据机器学习模型的预测采取行动。

让我们看一下每个步骤的一些考虑因素。

在流数据上训练模型

ML模型是在历史数据上进行训练的。你应该训练多少数据呢?这取决于手头的问题。一般的建议是,你应该只在模型将来投入生产后可能遇到的相似数据上进行训练。此外,几年前的数据通常来自完全不同的环境,可能捕捉到今天不相关的趋势和关系。

因此,在对流数据进行训练时,你不太可能对整个历史存档进行训练。相反,你希望在最近的数据上进行训练,这里的"最近"指的是与即将接收到的数据具有相同特征的数据。"最近"在这个上下文中可能是过去三天(就像我们在图8-10中展示的异常检测示例中所示)或在环境保持不变的情况下的过去三年。

窗口式训练

如果您经常进行训练,且训练数据由相对较小的时间段组成,您可以使用滑动窗口流水线,如图8-11所示。当您正在推断时间序列(例如仅基于历史需求周期进行需求预测)时,这是非常常见的。

为此,您需要:

  1. 一个流水线,用于创建在时间窗口内的数据集。
  2. Google Cloud Vertex AI、AWS SageMaker、Azure Machine Learning等中的一个参数化训练数据来源的自动化训练流水线。 (训练流水线还将模型部署到一个端点,我们将在"流式ML推断"中讨论。)

请注意,这里的"流水线"一词指的是不同的事物。流水线涉及对运动中的数据进行处理,而训练流水线包括ML操作(预处理数据、训练模型、评估模型、部署模型等)。我们将在第11章中更详细地讨论ML流水线。

周期性训练

对于模型有效期较长的情况(大致为几天到几周),您可以使用定期作业来启动训练,如图8-12所示。训练作业将从数据仓库(DWH)或其他持久存储中检索数据,例如过去的一个月的数据。

您可以使用Google Cloud Scheduler在Google Cloud上安排Vertex AI ML训练流水线。在AWS上,通过AWS EventBridge支持SageMaker流水线的调度目标。在Azure上,Azure Machine Learning流水线支持定时触发(作为流水线设置),因此不需要外部调度程序来调用它们。 我们强烈不建议在流水线中让模型保持不变超过几周的时间。如果您认为模型将继续保持有效,请通过持续评估模型并在必要时进行重新训练来验证您的直觉。我们将在下一节中讨论这一点。

持续评估和重新训练

最复杂的情况是使用模型直到确定其不再适用为止。为了确定模型在性能上发生了变化,您将需要进行持续评估。例如,如果您有一个用于预测用户是否会购买商品的模型,您可以在几天后验证用户是否购买了该商品。然后,您可以基于两周前的预测进行每周一次的模型评估,现在已经有了真实的答案。当评估指标降到预设的阈值以下时,可以对模型进行重新训练(见图8-13)。

您还可以将持续评估方法扩展到检测特征漂移------如果 ML 模型的任何输入的分布发生变化(例如,如果重复购买的次数占所有购买的 10%,但现在已经增加到 20%),则可能希望对模型进行重新训练。

截至撰写本文时,只有 Vertex AI 支持设置对已部署模型进行持续评估查询和检测特征漂移的功能。要在 Vertex AI 中设置此功能,您需要定义一个评估查询,并打开已部署模型将特征和相应预测写入 DWH 的功能。定期运行评估查询,并使用生成的指标来确定是否需要调用流水线。

请参阅云服务提供商的文档,了解是否支持此场景。如果支持,机制可能相似。如果不支持,则必须以定制方式构建相应的流水线和功能。

流式 ML 推断

通常,在事件到达时调用已训练的 ML 模型并获取这些事件的 ML 预测。 可以将模型对象加载到流式管道中并调用模型的预测签名。这通常是调用 ML 预测的最有效方式。但是,它不适用于大型模型和项目。

例如,ML 预测可能被非 Python 代码和在没有 GPU 的硬件上运行的程序所需(例如,考虑一个必须自动识别装配线上的物品是否有缺陷的工业机器,或者一个需要拒绝有毒评论的 Web 服务器)。为了处理这些情况,通常将模型部署到一个端点,以便它可以作为微服务调用。然后,通过向其发送 HTTP 请求并将 ML 模型的输入作为有效负载传递来调用模型。

如果一次只调用一个事件,ML 推断效率不高。因为现代 ML 框架基于矩阵操作,如果传递一小批事件进行推断,则效率要高得多。这就是图 8-14 中所示的内容。

自动化操作

如果唯一需要的是让人类用户能够查看ML模型的预测并做出决策,将预测结果存入数据仓库就足够了,如图8-15所示。但是,如果需要系统根据ML模型的预测自动执行某些操作怎么办?您可以使用ML模型执行需要自动化的任务,比如自动向可能放弃购物车的人发放优惠券,或者创建更换即将损坏部件的工单。您可以通过Lambda、Fargate、Google Cloud Functions、Google Cloud Run或Azure Functions等云函数以无服务器方式调用这些操作。为此,您需要将满足报警条件的丰富事件的子集写入到一个位置,从中触发云函数(参见图8-15)。

我们已经查看了许多流处理的用例和场景,以及如何使用云原生技术设计和实现它们。根据您的需求构建自己的流处理解决方案的架构。例如,如果您将在流数据上进行机器学习,可以选择图8-11、8-12和8-13中的其中一种训练架构,并将其与图8-14或8-15中的推理架构结合使用。如果只进行分析,请不要使架构变得复杂------看看是否可以使用图8-8,仅在必要时添加后期处理架构(图8-9)。

总结

这一章重点介绍了云原生流处理架构,您了解到它们非常模块化,允许您从小规模开始,只在需要时添加功能。主要的要点如下:

  1. 在许多行业中,能够在事件进行时做出决策比在几分钟后做决策更有价值。
  2. 流处理架构非常模块化,您可以通过构建简单的系统,根据额外的需求逐步添加复杂性。
  3. 如果目标是为业务提供更及时的数据,则流处理摄取就足够了。
  4. 与流处理管道相比,微批处理通常更便宜,但流处理管道可以立即提供事件供查询,而微批处理涉及延迟(大于分块频率)。
  5. 随着数据使用方的增加,以及不可能预测不同使用方需要的转换类型,许多组织将数据管道从流处理ETL切换到流处理ELT。
  6. 如果DWH提供流式API,云原生应用程序可以省略本地代理并使用云客户端库执行插入操作。
  7. 对于从边缘设备的IoT设备流式传输的数据,请利用IoT特定功能,例如边缘SDK和边缘硬件设备。
  8. DWH对于高吞吐量和/或低延迟情况并不是一个好的解决方案。在这种情况下,使用Cloud Bigtable或DynamoDB等NoSQL分析存储。
  9. 让仪表板工具向云DWH推送查询,创建可重用的视图,并对一些视图进行实体化以优化性能和成本。
  10. 在时间序列分析中,将警报写入警报主题和DWH,以支持自主操作和人工探索。
  11. 对于点击流分析,请使用预构建工具,但通过后期处理管道来丰富点击流数据,改善身份拼接、隐私涂抹和机器人检测。
  12. 异常检测涉及两个流处理管道:一个用于计算长时间段内的聚类,另一个用于将传入事件与最近的聚类进行比较并引发警报。
  13. 对于弹性流式传输,请确保更新正在运行的管道。如果无法更新,请排空它们。不要简单地取消正在运行的生产管道。
  14. 如果训练非常频繁且训练数据包含相对较小的时间段,则可以使用滑动窗口流水线向ML训练流水线提供训练数据。
  15. 对于已训练模型在几天到几周内仍然有效的情况,可以使用定期作业来启动训练。
  16. 要确定部署的模型是否在性能上发生漂移,您需要进行持续评估。
  17. 因为现代ML框架基于矩阵运算,如果将一小批事件传递给推理,效率要高得多。
  18. 要支持自主操作,您需要将满足警报标准的一些丰富的事件(事件+预测)写入主题,从而触发云函数。

在下一章中,您将看到分布式架构的方法和技术概述,重点关注边缘计算,这是一种可以减少延迟、提高安全性和降低成本的模式。

相关推荐
limingade4 小时前
手机实时提取SIM卡打电话的信令和声音-新的篇章(一、可行的方案探讨)
物联网·算法·智能手机·数据分析·信息与通信
编程零零七4 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
Karoku0667 小时前
【网站架构部署与优化】web服务与http协议
linux·运维·服务器·数据库·http·架构
惟长堤一痕10 小时前
医学数据分析实训 项目四回归分析--预测帕金森病病情的严重程度
数据挖掘·数据分析·回归
Lill_bin10 小时前
深入理解ElasticSearch集群:架构、高可用性与数据一致性
大数据·分布式·elasticsearch·搜索引擎·zookeeper·架构·全文检索
zyhJhon10 小时前
软考架构-面向服务的架构风格
架构
nbsaas-boot10 小时前
微服务之间的安全通信
安全·微服务·架构
涛思数据(TDengine)11 小时前
TDengine 与 SCADA 强强联合:提升工业数据管理的效率与精准
大数据·时序数据库·tdengine
isNotNullX12 小时前
如何用SQL Server和Oracle进行数据同步?
大数据·数据库·sql·oracle
shiming887912 小时前
Python数据分析与可视化
开发语言·python·数据分析