DOD-ETL:用于近实时商业智能的分布式按需ETL
摘要
全球化市场的竞争动态要求企业掌握其内外部现实的信息。信息是一种宝贵的资产,有助于建立关键优势,使企业能够保持领先地位。然而,可靠且丰富的信息已不再是唯一目标。从数据中提取信息的时间范围决定了其有用性。本研究提出了DOD-ETL,这是一种以创新方式解决商业智能解决方案中主要瓶颈——抽取转换加载过程(ETL)的工具,可提供近实时的ETL能力。DOD-ETL通过结合按需数据流管道、分布式、并行且技术无关的架构,以及内存缓存和高效数据分区来实现这一目标。我们将DOD-ETL与其他用于执行近实时ETL的流处理框架进行了比较,发现DOD-ETL的执行工作负载速度最快可达10倍。我们已在一家大型钢铁厂部署该系统,替代了原有的ETL解决方案,实现了此前无法提供的近实时报表功能。
关键词 :近实时ETL,商业智能,大数据
如引今言,各组织迫切需要在日益竞争激烈的市场中寻找新的成功途径。实现这一目标并无简单的答案。但有一点显而易见:组织必须利用近实时且可靠的信息,才能在全球市场中蓬勃发展。
商业智能(BI)是一个术语,用于定义各种分析工具,这些工具提供对支持决策过程的信息的便捷访问 [1]。这些工具执行信息的收集、整合和分析,使公司内外各个层级都具备分析能力。换句话说,商业智能能够将收集到的数据进行统一和结构化,从而以直观且简洁的方式呈现,帮助组织进行企业决策。
提取转换加载(ETL)管道是商业智能(BI)工作流中的关键流程。它是为查询或分析而组织数据的过程。ETL由三个阶段组成,分别是:数据抽取、数据转换和数据加载,分别对应数据从其源中提取,进行相应结构化处理,最后加载到目标数据仓库中。在ETL过程中可以采用两种处理策略:(1)批处理和(2)流处理。它们之间的区别在于源数据是否有界(即已知且有限的大小)或无界(随时间逐渐到达)。
生产系统与BI工具的集成是ETL流程的责任,“这是商业智能最具挑战性的方面,需要耗费约80%的时间和精力,并产生超过50%的意外项目成本”[2]。正因为如此,ETL被视为商业智能中的关键任务流程,必须给予高度重视。及时获取当前且准确的数据对于商业智能应用的成功至关重要。然而,由于数据量巨大且操作复杂,现有的ETL解决方案通常运行时间较长,因而成为满足商业智能需求的障碍。
ETL面临的主要挑战在于数据抽取过程中数据源的性能下降,以及在短时间内对大量数据执行复杂操作。理想的解决方案具有两个相互冲突的目标:(1)不对数据源造成任何影响;(2)在数据生成或更新时进行近实时处理。理想方案应能够应对高数据量输入速率,并在短时间内执行复杂操作,同时以无操作开销的方式提取数据。批处理和近实时ETL的主要特征如图1所示。
萨布图等人[3]列举了与近实时ETL相关的问题,并与埃利斯[4]一起为每个问题提供了一些方向和可能的解决方案。然而,由于这些问题的复杂性,ETL解决方案并不总是直接应对这些问题:为了避免影响事务数据库的性能,ETL过程通常以批处理方式在非高峰时段运行(例如午夜之后或周末期间)。通过避开高峰期,减轻了对关键任务应用程序的影响。然而,在数据中提取信息的延迟决定其有用性的场景下,当ETL过程执行不频繁时,BI工具和决策会受到严重影响。
在本文中,我们提出了DOD-ETL(分布式按需ETL),这是一种技术独立的架构,结合多种策略以实现近实时ETL。DOD-ETL在数据抽取过程中对源数据库的影响最小,能够以与源端数据生成或更新相同的速度将经过转换的数据流传输到目标数据库,并具备可扩展性,能够应对数据量和复杂性的增长。我们通过协同结合多种通常被独立使用的技术和策略实现了上述目标(例如,在[5–8]中):基于日志的变更数据捕获(CDC)、流处理、集群计算、内存数据存储、用于保证连接一致性的缓冲区,以及高效的数据分区和统一编程模型。DOD-ETL以分布式的模式运行,在流处理框架之上进行优化,从而提升其性能。
我们基于Kafka[9]、波束[10]和Spark流处理[11]开发了DOD-ETL原型。我们在流处理框架上评估了使用和不使用DOD-ETL执行相同工作负载时的性能。研究发现,与未修改的流处理框架相比,我们的方案确实提供了更好的性能,能够将工作负载的执行速度提高多达10倍,同时提供水平可扩展性和容错性。
我们还在一家大型钢铁厂中评估了DOD-ETL,以替代其原有的ETL解决方案。DOD-ETL将ETL过程从数小时缩短至不到一分钟,从而实现了此前难以实现的重要近实时报告。
我们的主要贡献包括:(1)对商业智能和ETL过程的深入研究及文献综述;(2)设计了一种近实时ETL解决方案;(3)使用先进的消息传递技术、集群计算工具和内存数据库,将该方案实现为一个名为DOD-ETL的通用工具;(4)对DOD-ETL进行评估,包括在钢铁行业的实际部署。
本文其余部分组织如下。首先,在第1节中讨论近实时ETL的研究问题与挑战。接着,在第1节介绍相关工作,第1节介绍DOD-ETL及其设计所基于的假设,并详细说明其实现与优化。我们在第1节评估性能、可扩展性和容错性。最后,在第1节总结主要发现并提出未来工作。
研究问题和挑战
由于企业面临在越来越短的时间范围内进行决策的压力日益增加,数据仓库需要实时或在尽可能短的时间间隔内进行更新。这一要求导致近实时ETL概念的提出,这是一个具有挑战性且重要的研究主题,其主要定义、问题和概念由瓦西里亚迪斯和西米奇斯[12]。
与近实时ETL相关的其他新兴概念是主动数据仓库[13],[14]和实时商业智能[15–17]。两者描述了一种新的商业智能范式,其中数据以近实时的方式更新,并且决策及相应操作均自动执行。
埃利斯[4]指出,处理近实时ETL需要在每个ETL阶段解决三个关键特性:高可用性、低延迟和水平可扩展性,这些特性可确保数据持续流动并保持可用,为业务提供最新的信息。
维博沃[18]和萨布图等人[3]指出了开发近实时ETL系统所面临的问题与挑战。此外,埃利斯[4]也识别了相关挑战,并提供了应对这些挑战的方向。具体而言,他们指出,与多个异构数据源的集成、性能限制、数据不一致,以及备份和主数据开销是需要解决的实际挑战。
我们在此工作中回答的主要研究问题是:如何实现近实时商业智能方法?我们认为该问题的答案并非显而易见,因为此类解决方案带来了多项要求:
- 高可用性
- 近实时延迟;以及
- 水平可扩展性。
这些需求中的每一项都会增加复杂性,而复杂性(由需求本身引起)又会对每一项需求产生负面影响,从而导致冲突。我们提出并评估了一种设计,该设计实现了积极的权衡,并满足了这三个要求。第1节描述了我们在设计中结合的解决方案。具体而言,我们的主要思路是:(1)一种将不同信息源划分为最小集合的新方法,以最小化数据重复并支持并行计算;(2)使用内存缓存来汇总数据,以支持报告的增量式、可扩展生成。
相关工作
本节分为五个主题。前三个主题介绍了尝试解决第1节中描述的问题的已发表工作:数据源集成、主数据开销、性能下降和备份。第四个主题关注流处理框架方面的出版物,这是近实时ETL解决方案的一个重要因素。至于最后一部分,我们比较了DOD-ETL与相关工作的差异。
数据源集成
Mesiti等人[5]利用流处理范式,使处理器能够并发工作,以集成多个异构的传感器数据源。该研究将集成挑战推向了一个更为复杂的领域,即数据源的异构性和多样性更加突出:以传感器作为数据源。纳伊姆等人[6]通过提出一种基于推送技术并结合数据库队列的事件驱动近实时ETL管道,解决了近实时ETL问题。
张等人[7]提出了一种新框架,用于处理医疗科学应用中的流式数据。该框架(1)实现了来自多个数据源、具有不同到达速率的数据集成;(2)估计工作负载,以便规划计算资源进行适当扩展。他们扩展了Hadoop[19] Map-Reduce框架,以应对流式数据变化的到达速率。为了估计未知的工作负载特征,他们提出了两种预测流式数据工作负载的方法:平滑法和卡尔曼滤波。
瓦斯等人[20]提出了一种基于流的ETL新方法。他们的方法首先从数据源导入原始记录,仅在报表需要时才执行转换和数据清洗。换句话说,他们将ETL重新排序为ELT,因此数据在需要时按需进行转换和处理。为了实现这种ELT,他们开发了一种监控工具,用于向所有连接的组件发出有关新到达数据的警报。
将ETL重新排序为ELT的策略可以受益于数据库复制技术,这些技术由数据库自身嵌入并协调。在这种情况下,副本可用于执行ELT的transf ormation步骤。
数据复制是一个复杂的主题,包含多种方法。Wiesmann等人[21]开发了一个框架,用于在多个维度上比较不同技术,包括同步与异步、分布式与集中式,或数据存储后端。我们更关注分布式数据库上的异步复制[22, 23]:这些解决方案能够通过异步事务复制提供强一致性,同时不会显著降低性能。
主数据开销
纳伊姆等人[6]还尝试通过设计一种在转换阶段管理主数据的新方法来最小化主数据开销:他们将数据划分为更静态的主数据和更频繁更改的事务数据,并将主数据存储在存储库中。该策略使其在转换步骤中的使用更加高效。
许多研究聚焦于主数据开销问题,其中数据流与主数据之间的连接可能导致性能瓶颈。为最小化这些瓶颈,他们提出了针对这些连接的优化策略[24–27]。
性能下降和备份
根据瓦西里亚迪斯和西米奇斯[12],通过变更数据捕获(CDC)是从数据库中提取数据且开销最小的最有效方法之一。他们还指出,执行CDC提取的一些技术包括:
- 在源数据库中创建触发器以通知每次数据修改。
- 数据库中事务的时间戳允许定期提取新记录(即时间戳大于上次提取时间戳的记录)。
- Logsstore将更改写入数据库,之后可由依赖该数据的系统进行处理。
尽管贾因等人[8]使用两个指标比较了变更数据捕获方案以识别数据源过载,施等人[28]则提出了一种变更数据捕获框架来评估其性能。两者均得出结论:基于日志的变更数据捕获效率最高,对数据库性能影响最小,并能最大限度减少数据丢失。因此,通过日志执行抽取阶段可以在不降低性能的前提下提供低延迟。
需要指出的是,如前所述,变更数据捕获可在副本数据库中启用。也就是说,可以将两者结合,以减少性能下降并提高备份弹性。
流处理框架
上述出版物提出了应对近实时ETL解决方案三大主要特性(高可用性、低延迟和水平可扩展性)相关挑战的策略。每项研究都独立关注特定问题。然而,流处理范式在大多数解决方案中呈现出共性,这与近实时ETL的要求相一致。
在这种基于流的应用场景中,多种流处理框架有助于此类应用的开发,或被直接用于满足近实时ETL需求。这些框架大多基于逐条记录处理模型,即每条记录被独立处理。采用该模型的流处理器框架示例包括雅虎的S4[29]和推特的Storm[30]。
与这种逐条记录处理模型相比,另一种方法是将其建模为一系列小的确定性批处理计算,正如扎哈里亚等人在Spark流式处理框架中提出的[11]。这种方式带来了诸多优势,其中包括与批处理系统的集成,由于避免了逐条记录操作,实现了简便性并减少了性能开销。Flink[31]目前正作为重量级数据处理的开源框架与Spark流处理竞争。它还在一个管道中融合了流处理与批处理,并具备灵活的窗口机制和精确一次语义等功能。
除了这些开源框架外,还有云服务提供商提供的服务,例如Google Dataflow[32]和Azure Stream Analytics[33]。使用这些服务可以避免安装和配置的开销,资源分配也更容易实现水平可扩展性。
这些开源框架和流处理服务均面向通用用途设计。由于其一刀切架构,它们缺乏DOD-ETL所采用的策略和优化。此外,尽管上述论文提出了针对特定问题或挑战的解决方案,DOD-ETL则将所有挑战的解决方案集成于单一工具中。最后,我们指出,我们为DOD-ETL提出的扩展具有通用性,可集成到任何流处理框架中。
DOD-ETL与先前工作的对比:改进与权衡
我们发现,任何近实时ETL解决方案都必须具备三个关键特性[4]:高可用性、低延迟和水平可扩展性。然而,我们也发现,要实现这些特性,仍存在一些具有挑战性的问题需要解决[3, 18]。
表1总结了近实时ETL的一些主要问题、解决这些问题的关键工作以及所采用的相应解决方案。
| 问题 | Work | 解决方案 |
|---|---|---|
| 多个和异构的数据源 | Mesiti等人[5] | 流处理 |
| 纳伊姆等人[6] | ||
| 张等人[7] | ||
| 瓦斯等人[20] | ||
| 性能退化和备份数据 | 瓦西里亚迪斯和西米奇斯[12] | 日志CDC* |
| 贾因等人[8] | 触发器CDC | |
| 石金刚等人[28] | 时间戳CDC | |
| 主数据开销 | 纳伊姆等人[6] | 主数据存储库 |
| Polyzotis, Neoklis, 等.[24] | 连接优化 | |
| Bornea, Mihaela A.,等[26] | ||
| Naeem, M.Asif等[27] | ||
| 张等人[7] |
准确地说,它指出了ETL面临的主要问题:(1)多个且异构的数据源,(2)性能下降和备份数据,以及(3)主数据开销问题;以及相应的现有方法:(1)流处理,(2)变更数据捕获,(3)主数据存储库或连接优化。
DOD-ETL结合了多种以往单独使用的策略,以实现近实时ETL。值得注意的是,DOD-ETL采用了表1中提到的大部分策略:它通过流处理从CDC中提取更改,并使用内存数据库缓存主数据。此外,DOD-ETL利用集群计算框架的功能以及流处理中的数据复制,以确保容错性并防止数据丢失。
话虽如此,DOD-ETL采用了不同于以往研究的策略,以进一步提升其性能。例如,与Naeem等人[6]使用中央存储库的方式不同,DOD-ETL在每个处理集群节点上部署内存数据库,用于提供主数据。该策略使得处理节点能够及时访问主数据。DOD-ETL还支持具有不同到达速率的数据之间的集成,类似于张等人[7],但采用了不同的策略。张等人[7]使用自适应算法来配置资源并缓存不同步数据,而DOD-ETL则使用缓冲区来存储所有延迟数据及其时间戳。在按需转换能力方面,Waas等人[20]先加载数据,并仅在请求时触发转换,而DOD-ETL利用变更数据捕获(CDC)技术,仅在发生更改时以相同的速度处理数据。与在处理请求时才进行数据转换的传统ETL解决方案相比,这使得数据能更快地提供给消费者使用。
上述每一点将在第1节中进一步详细描述。
DOD-ETL
DOD-ETL依赖于具有分布式、并行和技术无关架构的按需数据流管道。它结合使用流处理和内存中的主数据缓存以提高性能,利用缓冲区确保对到达速率不同的数据进行连接操作时的一致性,并通过统一的编程模型使其能够运行在多种流处理框架之上。此外,我们的方法充分利用了(1)数据分区以优化并行性,(2)数据过滤以优化DOD-ETL主数据缓存中的数据存储,以及(3)基于日志的变更数据捕获,以按需处理数据并对源数据库造成最小影响。因此,DOD-ETL具备:在抽取过程中对源数据库的影响最小、支持近实时工作、可扩展以应对数据和吞吐量增长,并且可以与多种流处理框架协同工作。
实现上述DOD-ETL特性的关键见解如下:
-
按需数据流
——当源数据库中的数据发生更改时,这些更改将被处理并加载到目标数据库中,形成一个数据流,ETL过程在可行的时间范围内仅处理最少量的必要数据。
-
分布式与并行
——以分布式和并行的方式执行所有步骤,缩短处理时间,并有效利用计算资源。
-
内存缓存
——在数据转换过程中无需回查源数据库,所有计算所需的数据均通过内存缓存提供,从而避免与数据源进行高成本的通信。
-
异步一致性
——缓冲区可确保具有不同到达速率的数据在转换过程中能够被连接。
-
统一编程模型
——一种用于在多个流处理框架中为批处理和流处理构建数据管道的编程模型。
DOD-ETL将多种策略和技术融合到一个解决方案中,这些策略和技术此前从未被集成以实现近实时ETL:基于日志的变更数据捕获(CDC)、流处理、集群计算以及内存数据存储,并结合高效的数据分区(参见第1节)。尽管这些技术确实已被使用过(例如,在[5–8])中),但它们之前并未被整合到单一解决方案中。通过协同结合这些策略和技术,DOD-ETL能够实现执行近实时ETL所需的全部三个关键特性:高可用性、低延迟和横向可扩展性。接下来的章节将详细阐述DOD-ETL的架构以及每个模块如何帮助解决近实时ETL面临的挑战。
架构
DOD-ETL具有以下工作流(图2):(1)它跟踪每个源系统数据库表的更改,并(2)根据预配置的分区标准将这些更改作为消息发送到(3)消息队列。然后,(4)这些消息从消息队列中被拉取并发送到内存缓存,或(5)被转换为目标报表技术格式,最后(6)加载到目标数据库中。DOD-ETL的工作流可分为两个核心模块:变更追踪器和流处理器。
所有步骤都依赖于配置参数才能正常工作。因此,在部署DOD-ETL时,必须进行配置过程,以确定以下参数:
-
tablesto extract
——定义将从中提取数据的表;
-
table nature
——从已定义的表中,明确哪些是操作型(持续更新)的表,哪些是主数据(半静态)的表;
-
primary key
——为每个表,包含每行唯一标识符的列集合;
-
业务键
——对于每个表,用于按特定领域键对数据进行分区或过滤的列集合。
变更追踪器
变更追踪器会立即将源数据库中发生更改和新增的数据作为事件实时提供给流处理器模块。该模块利用变更数据捕获(CDC)这一标准数据库模式,记录随着时间执行的所有操作及其对应值。因此,每当一条记录被插入、修改或从表中删除时,变更数据捕获(CDC)便会写入该事件以及该记录的全部信息。
变更数据捕获可以有多种形式,从数据库中的日志文件到结构化表。它们可以由数据库本身或外部系统生成。在这项工作中,按照贾因等人的建议[8],采用了基于日志的CDC。然而,如后文所述,DOD-ETL中的CDC读取步骤由监听器执行;得益于DOD-ETL的模块化架构,通过创建不同的监听器可以支持新的CDC实现。
变更追踪器的工作分为三个阶段,分别是监听器、消息生产者和消息队列。监听器阶段负责监听变更数据捕获(CDC)的更改,并针对每条新记录提取其数据,以供消息生产者进一步处理。该阶段的设计允许从表中独立提取数据,从而实现并行化处理。因此,作为先决条件,监听器要求CDC日志支持此功能。由于以下两个因素,监听器步骤对源数据库的性能影响最小:(1)仅提取新增和修改的记录,从而最小化数据量;(2)查询仅在日志文件中进行,减轻了数据库和生产表的压力。由于监听器步骤被设计为与其他两个步骤解耦,因此可以替换或扩展以适应源数据库的特定特性,例如不同的技术类型和变更数据捕获实现方式。
消息队列充当消息代理,并采用具有分区功能的发布/订阅模式,其中每个主题根据其键进行分区。在DOD-ETL中,一个主题包含一张表的所有插入操作、更新操作和删除操作。主题的分区标准根据该主题所代表的表的性质(主数据或操作型数据)而有所不同。在处理主数据表时,每个主题按其对应的主键进行分区;在处理操作数据时,每个主题按业务键进行分区。此分区操作发生在消息生产者端,在其发布每条提取的数据之前,依据上述配置参数进行。因此,消息生产者将监听器提取的数据构建成消息,并根据预配置的参数将其发布到消息队列中的相应主题。这两种分区策略(按主键和按业务键)具有以下目标:
- 主键 :由于主键是主题的分区键,消息队列保证了对特定表行的消息消费将按正确顺序进行。此外,由于主键的新消息会覆盖先前消息,因此只需获取每个分区键(主键)的最后一条消息,即可重构数据库的快照。
- 业务键 :流处理器的转换过程基于操作主题及其业务键定义的分区数量进行并行化。因此,分区标准直接影响DOD-ETL的性能。在此意义上,预先了解提取的数据以及流处理器将执行的操作性质至关重要。目标是确定分区准则及其键,因为它们可能根据业务性质的不同而有所变化。
分析主要的近实时功能及数据抽取面临的挑战后,我们得出结论:使用基于日志的变更数据捕获(CDC)能够仅处理数据变更,从而实现低延迟且不会造成性能退化和高可用性,并在需要时恢复快照。由于变更追踪器从每个配置表独立提取数据,因此保证了随着可用分区键数量增加而实现的数据抽取可扩展性。消息队列所使用的分区标准(业务键和主键)确保了数据消费的水平可扩展性。在这种情况下,它使流处理器能够实现扩展。
图3提供了变更追踪器API接口的概览。我们注意到,监听器和消息生产者均被构建为接口,以便通过不同功能进行扩展和替换,例如,适应不同的数据库和消息队列限制。该图还显示所有模块均为参数化,例如,允许配置并行数据提取任务的数量,或生成的消息的分区键。
流处理器
流处理器通过订阅消息队列上发布的所有主题,从监听器接收数据,获取所有最近更改的数据作为消息流。流处理器包含三个步骤:(1)内存表更新器,(2)数据转换器和(3)目标数据库更新器。
内存表更新器 通过创建并持续更新包含执行数据转换所需补充数据的分布式内存表,避免了对源数据库进行代价高昂的回溯查询。来自主数据表对应主题的数据流入内存表更新器步骤。内存表更新器仅保存与其对应的流处理器节点所分配的业务键相关的数据,并按该键进行消息过滤。通过这种方式,只有该节点将要处理的键的数据才会被保存在其内存表中,从而降低内存压力。在发生节点故障、数据丢失或两者同时发生的情况下,流处理器会从消息队列获取快照,并重新填充已失效的内存表。这得以实现的原因在于每个消息队列的主数据主题的建模方式:它按表的主键,允许内存表更新器从消息队列中检索该主题表的精确快照。
数据转换器 接收数据并执行操作,将其转换为所需的商业智能报表格式。数据转换器可以在内存表上运行时点查询,以获取执行其操作所必需的缺失数据,并高效地连接流式和静态数据。每个分区都并行处理,从而提升性能。在数据转换器中执行的操作依赖于集群计算框架的算子(例如映射、归约、过滤、分组),并且这些操作是与业务相关的。与内存表更新器类似,并非所有消息都会经过此模块,只有来自被配置为操作型的表的消息才会通过。对于主数据事件在操作数据之后到达的情况(主数据和操作数据消息被发送到不同的主题,并由不同的监听器实例发送),数据转换器使用操作消息缓冲区来存储(提前到达的)操作数据消息,以便在接收到(延迟的)主数据后重新处理。当新的主数据到达时,数据转换器会检查缓冲区中有无待处理的操作消息,并结合新的主数据对其进行重新处理。为了优化性能,数据转换器仅重新处理事务日期早于内存缓存中最新交易日期的缓冲消息,从而避免重新处理那些仍然缺少主数据的操作消息。
如第1节更详细所述,DOD-ETL的性能高度依赖于数据模型和转换操作的复杂性。也就是说,数据本身及其转换方式(在此情况下由流处理器完成)是影响DOD-ETL处理速率的关键因素。
目标数据库更新器 将数据转换器的结果转换为查询语句,然后将这些语句加载到目标数据库中。为了提高性能,加载过程也是并行进行的,每个分区独立执行其查询语句。
由于流处理器和消息队列采用了流处理和发布/订阅方法,来自多个异构源的数据可以同时被处理。此外,结合高效的分区策略使用流处理框架,能够实现高可用性和水平可扩展性。通过使用内存缓存和操作消息缓冲区,DOD-ETL能够以低延迟处理数据,因为主数据可以及时获取。这些方案共同实现了第1节中介绍的DOD-ETL的全部三个关键特性。
如流处理器API统一建模语言(图4)所示,流处理器具有一个名为消息消费者的接口,用于实现所选消息队列的特定功能。目标数据库更新器模块也具有一个接口,以实现类似的灵活性。这两个模块能够适应部署环境或软件栈。由于数据转换器的转换因业务而异,因此它也有一个名为业务领域的接口,用于整合业务模型和转换。
可扩展性、容错性和一致性
DOD-ETL利用了所采用的集群计算框架和消息队列对可扩展性和容错性的原生支持。在容错性方面,DOD-ETL的两个模块都能够处理节点故障,但采用了不同的策略:变更追踪器侧重于在无消息丢失的情况下,流处理器专注于无处理任务丢失。至于可扩展性,两个模块都依赖于高效数据分区来实现适当的扩展。
尽管继承了这些功能,为了使容错性和可扩展性符合DOD-ETL的架构,仍需在流处理器上实现某些特性:内存缓存和操作消息缓冲区必须能够检索之前存储在已失败节点上的数据或来自新节点的数据。关于内存缓存,我们实现了一个触发器,在数据转换器所分配的业务键发生更改时通知内存表更新器。当发生更改事件时,内存表更新器会重置内存缓存,从消息队列中转储最新的快照,并按所有已分配的业务键进行过滤。通过这种方式,内存缓存在发生故障事件或集群扩容、缩容时,能够与流处理器的重新分配过程保持同步。至于操作消息缓冲区,它使用消息队列内置的分布式配置服务来保存其配置:当某个节点发生故障时,其他流处理器实例可以接管处理任务。也就是说,操作消息缓冲区保存所有主数据延迟的操作消息,并且每收到一条新消息,数据转换器都会尝试通过检查内存缓存中对应的主数据是否已到达,来重新处理该缓冲区,从而解决消息到达不同步的问题。
由于DOD-ETL专注于向信息系统提供数据,而非操作型关键任务系统,因此事务原子性不是必需的,也不在本工作的范围之内:同一事务中添加/修改的不同表的行可能在略有不同的时间到达。然而,由于其较晚的操作消息缓冲区机制,DOD-ETL可以保证仅处理具有引用完整性的数据,并且暂时不一致的数据最终也会被处理。如前所述,当所有所需数据到达内存缓存时,数据转换器会重新处理操作消息缓冲区中的所有消息。
实现
DOD-ETL是一个由多个部分组成的工具:变更数据捕获、监听器、消息队列、流处理器。其中监听器是全新构建的,而变更数据捕获和消息队列则直接采用现成的解决方案,流处理器是在统一编程模型基础上进行了定制和优化的流处理框架。其具体实现和技术将在下文说明。
DOD-ETL模块之间交换的所有数据均由Avro系统进行序列化和反序列化[34]。MessageQueue角色由Kafka承担[9],一个异步实时消息管理系统,其架构为分布式的且具备容错性。由于Kafka对Zookeeper的依赖[35],也被DOD-ETL使用。
流处理器使用波束[10]实现,波束是一种统一编程模型,可用于Spark流处理和Flink等流处理框架之上。其步骤包括数据转换器、内存表更新器和目标数据库更新器,这些组件被封装在一起,以便它们之间的通信更加便捷。数据转换器利用Zookeeper依赖关系来存储其延迟的操作消息缓冲区,以确保在发生任何失败事件时,另一个流处理器节点能够继续处理这些延迟的消息。
关于内存缓存,使用了H2[36]并将其作为嵌入式数据库部署在流处理器上。为了支持DOD-ETL的需求,H2被配置为内存中运行的嵌入式数据库,因此对于每个Spark工作节点,我们都可以拥有一个H2实例以实现快速通信。我们的原型及其模块是公开可用的1。
由于DOD-ETL模块设计为解耦的,因此每个模块都可以在不影响其他模块的情况下进行扩展或替换。再加上其技术无关性特点,只要满足相应需求,每个模块中所选的技术均可被替换。
1 https://github.com/gustavo-vm/dod-etl
DOD-ETL:用于近实时商业智能的分布式按需ETL
案例研究
我们以一家大型钢铁厂及其商业智能流程为案例研究。在此案例中,使用了一个关系型数据库作为数据源,该数据库由生产管理系统和车间级设备共同支持。该钢铁厂具有以下特征:总面积为4,529,027 m²,建筑面积为221,686 m²,2238名员工,并专注于生产特殊棒材质量(SBQ)钢材。
该钢铁厂使用OLAP报表[37]作为其商业智能工具。DOD-ETL被用于为这些报表提供近实时更新。作为对比,在部署DOD-ETL之前,报表每天更新两次。DOD-ETL的目的是从源数据库中提取数据,并将其转换为联机分析处理所期望的模型,即星型模式[38]。此转换过程涉及对该钢铁厂流程的关键过程指标(KPIs)进行计算。在本案例研究中,选择了用于支持全面生产维护(TPM)[40]计划的设备综合效率(OEE)[39]及其相关指标(可用性、性能和质量)作为该钢铁厂的关键绩效指标。
TPM是一种用于设备维护的策略,旨在通过实现以下目标来追求最优生产:无设备故障;无设备运行速度低于计划;无生产损失。
OEE通过提供准确的度量指标来跟踪实现最优生产的进展,与TPM举措密切相关。也就是说,以下关键绩效指标可以量化上述三个目标:
-
可用性
——衡量生产损失,跟踪设备停机时间与其计划生产时间的对比;
-
性能
——跟踪设备实际生产速度与其最大理论速度的对比;
-
质量
——衡量由制造缺陷导致的损失。
这三个指标共同构成OEE得分:一个全面反映制造有效性的数值。
DOD-ETL仅提取了计算这些指标所需的数据。在此行业背景下,我们将数据分为以下几类:
-
productiondata
—生产部件的信息;
-
equipment data
—设备状态信息;
-
qualitydata
—已生产部件的质量信息。
在DOD-ETL配置过程中,做出了两个决策:我们定义了每个表的性质(操作型和/或主数据),并确定哪个表列将作为流处理器的业务分区键。关于表的性质,我们认为生产分组属于操作型,而设备和质量属于主数据。由于这一决策,所有发送到流处理器的设备和质量数据都将存储在其内存缓存中,而生产数据将直接进入流处理器的数据转换器步骤。
关于业务键,我们考虑使用生产设备单元标识符,因为所有关键绩效指标都是针对它计算的。因此,我们在配置中将每个表中表示并存储相关设备单元代码的列设置为业务键。该列将被操作主题用于分区,并被内存缓存用作过滤条件。
在此行业背景下,数据转换器为支持OLAP多维报表而进行数据分割。针对上述关键绩效指标,我们将时间域中的交集定义为分割标准,其中最低粒度表示针对相关设备单元获取的所有数据之间的交集:生产、设备状态和质量。图5展示了此交集分析和数据分割的示例。在这种情况下,数据转换器搜索针对设备状态与生产数据之间的交集进行拆分,并将其分解为称为事实粒度的较小数据组。如图5中的示例所示,这些事实粒度可分为两组:(1)状态为“关闭”的设备,以及(2)状态为“开启”且有生产的设备。
如前所述,在拆分过程完成后,数据转换器执行计算。
实验评估
为了评估我们的DOD-ETL原型的性能,我们使用Spark流式处理框架[11]作为基线。我们生成了一个合成工作负载,模拟钢铁厂设备发送的数据,并在其上执行了有和没有DOD-ETL的Spark。我们还进行了实验,以验证DOD-ETL是否实现了埃利斯的关键特性[4](高可用性、低延迟和横向可扩展性),并且作为我们工作的差异化部分,我们使用来自钢铁厂的生产工作负载执行了DOD-ETL,以检查其在复杂且真实场景中的行为。
总之,我们评估了以下四个方面:
1.
DOD-ETL与基线的对比
,检验Spark在使用和不使用DOD-ETL时的性能表现;
2.
水平可扩展性
,分析计算资源增加时的处理时间变化;
3.
容错能力
,评估在计算节点发生失败时DOD-ETL的行为表现;
4.
DOD-ETL在生产环境中的应用
,将其性能与钢铁厂的实际工作负载和复杂数据库模型进行比较。
我们使用了谷歌云,资源根据需要进行扩展,第五次实验除外,该实验使用了钢铁厂的计算基础设施。所有谷歌云平台实例均采用英特尔Haswell作为CPU平台,并使用硬盘驱动器作为持久存储。为了表示之前提到的三个数据类别,在实验1、2和3中,每个数据模型组使用了一张表。对于第四次实验,我们使用了一个基于ISA-95标准的更复杂的数据模型[41]。所使用的硬件、软件和配置如下(表2):
| 模块 | 软件 | 硬件 | 实例 |
|---|---|---|---|
| 数据库 | MySQL数据库 | 8核10GB | 1 |
| 采样器 | Python脚本 | 20核18GB内存 | 1 |
| 跟踪器 | Python脚本 | 20核18GB内存 | 1 |
| 消息队列 | Kafka | 一个核心和2GB内存 | 3 |
| Zookeeper | Zookeeper | 一个核心和2GB内存 | 3 |
| 流处理器 |
Spark流处理
DOD-ETL任务 | 一个核心和2GB内存 | 从1到20 |
对于实验1、2和3,如上所述,我们构建了一个采样器来在每个数据库表中插入记录。该采样器生成合成数据并插入每张表2万条记录,模拟钢铁厂操作。为了尽量减少这些实验中外部变量的影响,监听器在采样器完成执行后才开始数据抽取。为了避免对结果产生影响,变更追踪器在流处理器执行之前提取所有数据,以便消息队列能够按照流处理器请求的速率发送数据。由于监听器依赖于CDC日志的实现,其数据抽取性能也受其影响。我们使用MySQL作为数据库,并以其二进制日志作为CDC日志。
DOD-ETL与基线
由于DOD-ETL由现成组件组成,模块以解耦架构结合。为了评估DOD-ETL的性能,需要对每个模块进行单独分析。
如前所述,监听器高度依赖于所使用的数据库和CDC实现,其性能与它们紧密相关。因此,监听器以CDC吞吐量作为其基线。由于从写入数据库到将其复制到二进制文件的整个流程涉及大量I/O,监听器始终能够读取比CDC所能提供的更多的数据。
由于消息队列是一种现成的解决方案,只要满足其需求,就可以被任何其他解决方案替代,因此其性能可以从现有解决方案的改进或新解决方案的开发中受益。目前,消息生产者和消息队列分别是Kafka生产者和Kafka代理的实例。Kreps等人[9]已经证明了其相对于其他消息系统的性能。
流处理器在Spark流式处理框架基础上进行了大量定制(数据转换器、内存表更新器和目标数据库更新器)。我们评估了其在启用和不启用DOD-ETL的情况下执行相同工作负载的性能。我们使用了固定数量的Spark工作节点(表3):一个包含十个节点的集群。
| 基线 | 容错 | 生产 |
|---|---|---|
| DOD-ETL | Spark正常 | 失败简单工作负载 |
| 10,090 | 1230 | 5063 |
| 10,090 | 230 |
如表3所示,DOD-ETL能够每秒处理10,090条记录。相比之下,仅使用Spark流处理每秒仅能处理1230条记录,处理记录数减少了十倍。查看Spark作业执行日志(图6),其中显示了每个Spark工作节点任务的处理时间(毫秒),可以发现存在初始化开销。该开销是由于内存缓存启动所致:当分配一个新的业务键时,会从消息队列中提取所有相应的主数据。在本实验中,每个Spark工作节点的初始化开销为40秒。
在整个实验过程中,我们能够证明DOD-ETL的定制化使Spark显著加快。尽管由于消息队列中内存表更新器的数据转储带来了一定的初始化开销,但考虑到处理的消息量,该开销极小且可忽略不计。换句话说,DOD-ETL相比基线能够以更高的速率处理数据,提供的低延迟性能优于基线,更好地实现了近实时ETL的三大特性之一。
接下来的实验将表明,DOD-ETL的定制不会对Spark流处理的容错性和可扩展性产生负面影响。这得益于高效数据分区策略、操作消息缓冲区、消息队列和内存缓存之间的协同作用。
可扩展性
我们评估了DOD-ETL的变更追踪器和流处理器模块的可扩展性。为了评估监听器的性能,我们进行了两个不同的实验:
1.
Same number of input and output tables
,其中输入表(从中提取数据的表)和输出表(插入数据的表)的数量从1增加到16;
2.
Fixed number of output tables
,其中数据被插入到16个表中,而提取数据的表的数量从1增加到16。
如图7所示,每秒插入的记录数随表的数量变化而变化,监听器在每次实验中表现出不同的性能:当输入表和输出表数量相同时,监听器的性能以亚线性函数增加,然后在八个表时达到饱和,每秒18,600条记录。当使用固定数量的输出表时,性能呈线性增长,直到同时从八个表中提取数据时也达到饱和,吞吐量为每秒10,200条记录。
这种行为与MySQL的CDC实现直接相关,因为它将所有表的更改写入同一个日志文件中,因此每个监听器实例都必须读取整个文件以提取其对应表的数据。第一次实验的吞吐量高于第二次实验,原因是日志文件大小不同:在输出表数量固定的实验中,CDC日志文件的大小固定为32万条记录;而在输出表数量变化的实验中,CDC日志文件的大小从2万条记录到32万条记录不等。因此,在达到16个表之前,遍历整个日志文件所需的时间更短。饱和点是MySQL性能的函数,我们推测它在不同数据库和CDC实现之间会有所不同。
如前所述,消息生产者和消息队列分别是Kafka生产者和Kafka代理的实例。克雷普斯等人[9]已经证明,每个生产者每秒能够生成的消息数量比监听器能处理的数量高出几个数量级。至于其代理,其吞吐量更多地受到硬件和网络限制的影响,而非软件本身,这也使其能够处理更多的消息。
为了评估流处理器的可扩展性,我们将可用的Spark工作节点数量从1个增加到20个,并将操作主题上的分区数量固定为20个。为了最大化并行化,采样数据中的设备单元(分区键)数量与主题分区数量保持一致:采样数据包含20个设备单元标识符,用于作为分区键。我们使用了Spark流式查询进度的指标每秒平均处理行数在其每个微批任务中。如图8所示,每秒处理的记录数与Spark工作节点数量之间的关系。
DOD-ETL模块具有可扩展性:尽管变更追踪器和流处理器在吞吐量和可扩展性因子上存在差异,但两者都可以通过增加计算资源来应对增长。变更追踪器的扩展与表的数量成正比,而流处理器则随着操作型表上分区键数量的增加而扩展。
关于变更追踪器,我们了解到监听器和消息生产者可以独立处理表,并且随着新表的加入,系统能够进行扩展,前提是数据库的CDC日志支持该操作。至于消息队列,它也可以线性扩展,但取决于多个变量:可用代理的数量、提取的表(主题)、分区和键。
流处理器的可扩展性与操作型表主题的分区数量以及分区键的数量成正比,在本钢铁厂案例中,分区键的数量即为生产中设备单元的总数。数据分区在此起着至关重要的作用,因此必须从功能上提前充分理解所有提取的数据,以确定适用于不同业务场景的分区准则及其分区键。由于消息队列支持的吞吐量远高于监听器和流处理器,因此可以集成多个数据库源,并使用多个流处理器实例,每个实例执行不同的数据转换任务。
容错
我们在一个包含五个工作节点的集群中执行了DOD-ETL,并在实验中途关闭了其中两个工作节点,以评估DOD-ETL的容错能力。我们测量了关闭前后处理消息的速率,并对结果进行了数据一致性检查。我们使用了与可扩展性实验相同的性能指标(表3)。
流处理器的处理速率从每秒5060条消息下降到每秒2210条消息,代表处理速率下降了57%。每次执行后,我们检查了该模块处理的所有消息的一致性,未发现任何错误:尽管处理速率降低,但所有消息均被正确处理。该结果表明DOD-ETL具有容错性,显著提高了其鲁棒性。
当可用集群数量从5个减少到3个(减少了40%)时,性能下降更为显著(达57%)。通过分析Spark执行日志,我们发现内存缓存也会影响故障切换性能:当某个节点变得不可用并分配新节点时,内存缓存必须转储所有来自新分配分区键的数据,从而影响性能。
由于变更追踪器和流处理器分别基于Kafka和Spark构建,这两个模块都能够抵御节点故障。由于它们的目的不同,每个模块使用了不同的策略:Kafka可以配置为最小化消息丢失,而Spark可以配置为最小化处理任务的中断。
DOD-ETL在生产中的应用
我们使用钢铁厂的实际工作负载执行了DOD-ETL。该工作负载由生产管理系统和车间设备生成,其数据模型基于ISA-95标准,其中使用多个表来表示每个类别(生产、设备和质量)。我们将DOD-ETL在先前实验中的结果进行了比较,之前实验使用合成数据和更简单的数据模型(每个数据类别使用单个表),而DOD-ETL在真实且复杂的数据上执行(表3)。
合成实验和生产实验均使用相同的配置:包含十个Spark工作节点的集群。虽然DOD-ETL在处理数据模型复杂度简单的数据源时可以达到每秒10090条记录的处理速度,但在处理复杂数据模型时,该数值下降至每秒230条记录。因此可以得出结论:数据模型复杂度直接影响DOD-ETL性能。由于DOD-ETL依赖内存缓存来检索缺失数据,当此类检索涉及复杂查询时,这种复杂性会影响查询执行时间,从而影响DOD-ETL性能。
该钢铁厂目前使用一种ETL解决方案来执行与DOD-ETL相同的操作。该方案采用顺序批处理方法,包含一系列在关系数据库服务器内运行的程序,并依赖于十二核/32GB内存服务器。虽然DOD-ETL处理100条记录仅需0.4秒,但该解决方案需要一小时。尽管这一比较并不完全公平(流式分布式并行工具 vs 批处理和传统解决方案),但重要的是要证明DOD-ETL能够在关键条件下成功应用,能够吸收钢铁厂的数据吞吐量,并向其BI工具提供近实时的信息。
鉴于作者在开发关键任务制造系统方面的经验及其对ISA-95标准的了解,他认为这些系统在数据建模方面的弊端在于:采用标准化和通用的数据模型以寻求涵盖所有类型制造过程的单一视图,其缺点远大于优点。与特定于工艺的模型相比,使用通用数据模型的制造系统变得更为复杂,其性能、维护和架构都会受到严重影响,以适应这种通用模型。
因此,在此行业背景下,生产管理系统和车间可以采用更简单的数据模型而不会带来任何缺点。这样,DOD-ETL(以及其他可能的工厂系统)将表现得更加出色。
结论和未来工作
DOD-ETL的创新性在于将多种策略和优化(此前仅单独使用)与按需数据流管道以及分布式、并行和技术无关架构协同结合。
在本研究中,我们解决了主要的研究问题,即:如何实现近实时商业智能方法?近实时ETL系统需要具备三个关键特性:高可用性、低延迟和可扩展性。DOD-ETL通过结合基于日志的变更数据捕获(CDC)、流处理、集群计算、内存数据存储、用于保证连接一致性的缓冲区、高效数据分区以及统一的编程模型,成功实现了这三个关键特性并应对了这些挑战。
通过对其各个主要模块进行独立实验,我们已经能够证明,DOD-ETL的策略和优化能够减少ETL运行时间,性能优于现代流处理框架。通过这些实验,我们表明DOD-ETL在不牺牲可扩展性和容错性的情况下实现了这些结果。我们还发现,数据源模型的复杂性对转换阶段影响很大,并且DOD-ETL即使对于复杂模型也能成功使用。
由于其技术无关性,DOD-ETL可以使用多种流处理器框架和消息系统,只要满足相应要求即可。这使得DOD-ETL能够随着新技术的出现而适应和演进,并避免技术锁定。
实例化DOD-ETL需要自定义数据转换器步骤:每个所需的转换操作都被转化为Spark操作符,继而被编译为Java应用程序。这要求DOD-ETL用户具备编程能力,从而在一定程度上限制了其使用。为了克服这一问题,在未来工作中,DOD-ETL将被改进以集成一个带有直观可视化配置的友好的用户界面,用于数据转换器的转换操作。
关于未来工作,我们将通过新的实验研究使用轻量级流处理框架(如Kafka Streams和Samza)对DOD-ETL性能的影响。通过这种方式,我们将能够比较和评估这两类框架(轻量级与重量级)之间的权衡,以及它们对DOD-ETL策略和优化的影响。
总之,通过这项工作,我们结合多种策略和技术实现了近实时ETL,提出了一种通用工具,并在金属工业背景下对其进行了评估。
缩写
CDC:变更数据捕获;DOD:分布式按需;ETL:抽取转换加载;ISA:国际自动化协会;KPIs:关键过程指标;OEE:设备综合效率;OLAP:联机分析处理;TPM:全面生产维护计划

被折叠的 条评论
为什么被折叠?



