译者 | 陈峻
审校 | 重楼
如今,对于使用批处理工作流程的数据团队而言,要满足业务的实时要求并非易事。从数据的交付、处理到分析,整个批处理工作流往往需要大量的等待,其中包括:等待数据被发送到ETL工具处,等待数据被批量处理,等待数据被加载到数据仓库,甚至需要等待查询的完成。
不过,开源世界已对此有了解决方案:通过Apache Kafka、Flink和Druid的协同使用,我们可创建一个实时数据架构,以消除上述等待状态。如下图所示,该数据架构可以在从事件到分析、再到应用的整个数据工作流程中,无缝地提供数据的新鲜度、扩展性和可靠性。
目前,Lyft、Pinterest、Reddit和Paytm等知名公司,都在同时使用这三种由互补的数据流原生技术构建的应用,来共同处理各种实时用例。
用于实时应用的开源数据架构
上图展现的架构能够使得构建可观察性、物联网与遥测分析、安全检测与诊断、面向客户的洞察力、以及个性化推荐等实时应用,变得简单且易于实现。下面,我们将和您探讨此类工具的各个组成部分,以及它们将如何被结合起来实现广泛的实时应用。
过去,RabbitMQ、ActiveMQ、以及其他被用来提供各种消息传递模式的消息队列系统,虽然可以将数据从生产者分发到消费者处,但是其可扩展性十分有限。而随着Apache Kafka的出现,以及被80%的财富100强企业所使用,它已成为了流式数据的实际标准。其根本原因在于,Kafka架构远不止简单的消息传递,其多功能性使之非常适合在大规模的互联网上进行数据流传输。而其容错性和数据一致性,则可以支持各类关键性任务应用。同时,由Kafka Connect提供的各种连接器,也可与任何数据源相集成。
作为实时数据流平台的Apache Kafka
Kafka虽然能够提供实时数据,但是用户在需要兼顾实时效率和扩展性时,往往会选择Apache Flink。作为一个高吞吐量且统一的数据流批处理引擎,Flink的独特优势在于能够大规模处理连续的数据流。而作为Kafka的流处理器,Flink可以无缝地集成并支持精确的一次性语义(exactly-once semantics)。也就是说,即使在系统出现故障时,它也能保证每个事件被精确地处理一次。
具体而言,它会连接到Kafka主题,定义查询逻辑,然后连续输出结果,正所谓“设置好就不用管它(set it and forget it)”。这使得Flink非常适用于对数据流的即时处理和可靠性要求较高的应用案例。以下是Flink的两个常见用例:
如果数据流在使用之前需要进行诸如:修改、增强或重组数据等操作,那么Flink是对此类数据流进行操作的理想引擎。它可以通过持续处理,来保持数据的新鲜度。例如,假设我们有一个安装在智能建筑中的、温度传感器的、物联网遥测用例。其每一个被捕获的Kafka事件,都具有以下JSON结构:
{ "sensor_id":"SensorA," "temperature":22.5, "timestamp":“2023-07-10T10:00:00”}
如果每个传感器的ID都需要映射到一个位置,而且温度需要以华氏度为单位的话,那么Flink可以将JSON结构更新为:
{ “sensor_id”: “SensorA,” “location”: “Room 101”, “temperature_Fahreinheit”: 73.4, “timestamp”: “2023-07-10T10:00:00” }
并且将其直接发送到应用程序,或直接发回Kafka。
Flink数据处理的结构化表格示例
Flink在这方面的优势在于其处理大规模Kafka数据流的实时速度。此外,填充和转换通常是一个无状态的过程。每个数据记录都可以被修改,且无需维护其持久状态。因此整体工作量最小,且性能较高。
通过将Flink的实时持续处理和容错功能相结合,我们可以为各种关键性应用的实时检测和响应需求,设计出理想的解决方案。例如:当需要具备高检测灵敏度(如:亚秒级)和高采样率时,Flink的持续处理功能就非常适合作为数据服务层,被用于监控条件,触发警报,进而采取相应的行动。
Flink在警报方面的优势主要体现在:它既能够支持无状态警报,也可以支持有状态警报。例如:像“温度达到X时,通知消防队”这样的阈值或事件触发条件虽然简单,但不够智能。在一些真实的使用案例中,警报需要由能够保持状态的复杂模式驱动,甚至需要在持续的数据流中汇总各项指标(如:总量、平均值、最小值、最大值、以及计数等),而Flink则可以监控和更新状态,以及时发现偏差和异常。
值得注意的是,使用Flink进行监控和警报时,往往需要持续使用系统CPU来根据阈值和模式评估条件。这与只在执行查询时,才用到CPU的数据库有所不同。因此,您需要最好事先了解待开发的应用是否需要持续使用CPU。
总的说来,Apache Druid完善了数据架构,能够与Kafka和Flink一起成为支持实时分析的数据流消费者。虽然它是一个被用于分析的数据库,但是其设计中心和用途与其他数据库、以及数据仓库有较大的不同。
首先,由于Druid是数据流原生的,因此,Druid和Kafka之间不需要连接器,它可以直接连接到Kafka主题,并且支持精确的一次性语义。同时,Druid也被设计为用于大规模地快速捕获流数据,并在事件到达时,立即在内存中进行查询。
Druid如何与Kafka原生集成,以实现数据流捕获
在查询方面,Druid是一种高性能的实时分析数据库,可以在大规模和负载条件下,提供亚秒级的查询。它非常适用于那些对性能极其敏感,并且需要处理从TB到PB的数据(例如:聚合、过滤、GroupBy、以及复杂连接等)和高查询体量的用例。Druid不但能够持续提供快如闪电的查询,而且可以轻松从一台笔记本电脑扩展为由1000个节点组成的集群。这就是Druid被称为实时分析数据库的原因。以下是Druid与Flink的互补用例:
工程团队可以使用Druid支持包括:各种内部(即运营)和外部(即面向客户)涉及到可观察性、安全性、产品分析、物联网与遥测、制造运营等数据密集型分析应用。其核心特点包括:
这些应用要么具有交互性很强的数据可视化、以及合成结果集的用户界面,并得益于Druid的快速,能够非常灵活地即时更改查询;要么在很多情况下,它们利用Druid的应用程序接口(API)来提高查询速度,从而为决策工作流提供依据。
下图展示的是一个由Apache Druid支持的分析应用示例。
图片来源:Confluent的Confluent Health+仪表板
众所周知,由Apache Kafka原创的Confluent,可以通过Confluent Health+为客户提供分析服务。上图中的应用具有高度交互性。通常,事件会以每秒500万次的速度流向Kafka和Druid,该应用通过提供350 QPS的服务,来深入洞察客户的Confluent环境。
Druid与实时数据架构的关联之处在于,它可以提供实时数据与历史数据相结合的交互式数据体验,从而提供更丰富的语境。
如果说Flink擅长回答“现在发生着什么(即发出Flink任务的当前状态)”的话,那么Druid则在技术上能够回答“现在发生的与之前相比有何不同,哪些因素或条件对结果产生了影响”。回答这些问题将有助于消除误报,协助检测新的趋势,进而做出更有洞见的实时决策。
要回答“与以前相比情况如何?”的疑问,我们往往需要以过去的某一天、一周、一年或其他时间跨度,来进行相关性分析。而要回答“哪些因素或条件影响了结果”,我们则需要挖掘完整的数据集。由于Druid是一个能够实时分析的数据库,因此它可以捕获可供实时洞察的数据流,同时它也会持久性地保存数据,以便随时查询多维度的历史信息。
Druid 的查询引擎如何处理实时和历史数据
假设我们正在构建一个用于监控登录可疑行为的应用程序,那么我们可能希望在五分钟的时间窗口内设置一个阈值--更新并发布登录尝试的状态。凭借Druid,当前的登录尝试可以与历史数据相关联,以识别过去未发生、但的确被利用过的登录安全漏洞。据此,历史背景将有助于确定当前的登录反复尝试是否属于正常行为。
此外,如果您的应用程序需要接收大型批处理文件,且对瞬息万变的事件进行大量分析(如:当前状态、各种聚合、分组、时间窗口、以及复杂连接等),同时还要提供历史背景,并通过高度灵活的应用程序接口来检索数据集,那么这些都是Druid的优势所在。
可见,Flink和Druid都是为流数据而构建的。虽然它们有着一些高层次的相似之处,例如:都属于内存内部(in-memory)、都能扩展、都能并行,但是正如前文所述,它们的架构实际上是为完全不同的用例而构建的。下面,我为您整理了一份简单的、基于工作量来判断该如何选择的检查表:
总的说来,在大多数情况下,您的选择不会是“非Druid即Flink”,而是“既Druid又Flink”。它们各自的技术特性使得两者能够共同支持各种实时应用。
随着企业对于数据实时性的要求越来越高,数据团队需要重新考虑端到端的数据工作流程。这就是为什么许多公司已将Kafka+Flink+Druid作为构建实时应用的开源数据架构的原因。
陈峻(Julian Chen),51CTO社区编辑,具有十多年的IT项目实施经验,善于对内外部资源与风险实施管控,专注传播网络与信息安全知识与经验。
原文标题:Building a Real-Time Data Architecture With Apache Kafka, Flink, and Druid ,作者:David Wang