01.SpringBatch 介绍

2019-06-15  本文已影响0人  leofight

SpringBatch概述

Spring Batch是一个轻量级的、完善的批处理框架,旨在帮助企业建立健壮、高效的批处理应用。Spring BatchSpring的一个子项目,使用Java语言并基于Spring框架为基础开发,使得已经使用Spring框架的开发者或者企业更容易访问和利用企业服务。

Spring Batch提供了大量可重用的组件,包括日志、追踪、事物、任务作业统计、任务重启、跳过、重复、资源管理。对于大数据量和高性能的批处理任务,Spring Batch 同样提供了高级功能和特性来支持,比如分区功能、远程功能。总之,通过Spring Batch 能够支持简单的、复杂的和大数据量的批处理作业。

Spring Batch是一个批处理应用框架,不是调度框架,但需要和调度框架合作来构建完成批处理任务。它只关注批处理任务相关的问题,如事物、并发、监控、执行等,并不提供相应的调度功能。如果需要使用调度框架,在商业软件和开源软件中已经有很多优秀的企业级调度框架(如;QuartzTivoliControl-MCron等)可以使用。

使用场景

一般的典型批处理程序:

Spring Batch自动执行此基本批处理迭代,提供处理类似事务的功能,通常在脱机环境中处理,无需任何用户交互。批处理作业是大多数IT项目的一部分,Spring Batch是唯一提供强大的企业级解决方案的开源框架。

业务场景

定期提交批处理

技术目标

Spring Batch 体系结构

Spring Batch的设计具有可扩展性和多样化的最终用户群。下图显示了支持最终用户开发人员的可扩展性和易用性的分层体系结构。

Spring Batch分层架构

这种分层架构突出了三个主要的高级组件:应用程序,核心和基础架构。该应用程序包含开发人员使用Spring Batch编写的所有批处理作业和自定义代码。Batch Core包含启动和控制批处理作业所需的核心运行时类。它包括实现 JobLauncherJobStepApplicationCore都建立在通用基础架构之上。此基础结构包含常见的读取器和编写器和服务(例如RetryTemplate),应用程序开发人员(读取器和编写器,如ItemReaderItemWriter)以及核心框架本身(Retry,它是自己的库)都使用它们。

一般Batch原则和指南

在构建批处理解决方案时,应考虑以下关键原则,指南和一般注意事项。

批处理策略

为了帮助设计和实现批处理系统,应该以样本结构图和代码shell的形式向设计人员和程序员提供基本的批处理应用程序构建块和模式。在开始设计批处理作业时,应将业务逻辑分解为一系列步骤,这些步骤可使用以下标准构建块实现:

除了主要构建块之外,每个应用程序还可以使用一个或多个标准实用程序步骤,例如:

任何批处理系统的基础都是处理策略。影响策略选择的因素包括:估计的批处理系统容量,与在线系统或其他批处理系统的并发性,可用的批处理窗口。(请注意,随着越来越多的企业希望全天候运行,明确的批处理窗口正在消失)。

批处理的典型处理选项是(按实现复杂度的递增顺序):

商业调度程序可以支持部分或全部这些选项。

以下部分更详细地讨论了这些处理选项。重要的是要注意,根据经验,批处理采用的提交和锁定策略取决于所执行的处理类型,并且在线锁定策略也应使用相同的原则。因此,在设计整体架构时,批处理架构不能简单地成为事后的想法。

锁定策略可以是仅使用普通数据库锁或在体系结构中实现其他自定义锁定服务。锁定服务将跟踪数据库锁定(例如,通过将必要信息存储在专用db表中)并对请求db操作的应用程序提供或拒绝权限。此架构还可以实现重试逻辑,以避免在发生锁定情况时中止批处理作业。

1.批处理窗口中的正常处理对于在单独的批处理窗口中运行的简单批处理进程,其中在线用户或其他批处理过程不需要更新的数据,并发性不是问题,可以在批次运行结束。

在大多数情况下,更强大的方法更合适。请记住,批量系统随着时间的推移有增长的趋势,无论是复杂性还是处理的数据量。如果没有锁定策略并且系统仍然依赖于单个提交点,则修改批处理程序可能会很痛苦。因此,即使使用最简单的批处理系统,也需要考虑重启恢复选项的提交逻辑以及本节后面描述的更复杂情况的信息。

2.并发批处理或在线处理批处理应用程序处理可由在线用户同时更新的数据不应锁定在线用户可能需要的任何数据(数据库或文件中)几秒钟。此外,应在每次交易结束时将更新提交到数据库。这最小化了其他进程不可用的数据部分以及数据不可用的时间。

最小化物理锁定的另一个选项是使用乐观锁定模式或悲观锁定模式实现逻辑行级锁定。

这些模式不一定适合批处理,但它们可能用于并发批处理和联机处理(例如在数据库不支持行级锁定的情况下)。作为一般规则,乐观锁定更适合在线应用程序,而悲观锁定更适合批处理应用程序。每当使用逻辑锁定时,必须对访问受逻辑锁保护的数据实体的所有应用程序使用相同的方案。

请注意,这两种解决方案仅解决锁定单个记录的问题。通常,我们可能需要锁定逻辑上相关的记录组。使用物理锁,您必须非常小心地管理这些,以避免潜在的死锁。对于逻辑锁,通常最好构建一个逻辑锁管理器,该管理器了解您要保护的逻辑记录组,并确保锁是连贯的和非死锁的。此逻辑锁管理器通常使用自己的表进行锁管理,争用报告,超时机制和其他问题。

3.并行处理并行处理允许多个批处理运行或作业并行运行,以最大限度地减少总批处理时间。只要作业不共享相同的文件,db-tables或索引空间,这就不是问题。如果他们这样做,则应使用分区数据实现此服务。另一种选择是通过使用控制表来构建用于维护相互依赖性的体系结构模块。控制表应包含每个共享资源的行以及它是否正由应用程序使用。然后,批处理体系结构或并行作业中的应用程序将从该表中检索信息,以确定它是否可以访问它所需的资源。

如果数据访问不是问题,则可以通过使用额外的线程并行处理来实现并行处理。在大型机环境中,传统上使用并行作业类,以确保所有进程有足够的CPU时间。无论如何,该解决方案必须足够强大,以确保所有正在运行的进程的时间片。

并行处理中的其他关键问题包括负载平衡和一般系统资源(如文件,数据库缓冲池等)的可用性。另请注意,控制表本身很容易成为关键资源。

4.分区使用分区允许多个版本的大批量应用程序同时运行。这样做的目的是减少处理长批处理作业所需的时间。可以成功分区的进程是可以拆分输入文件和/或对主数据库表进行分区以允许应用程序针对不同数据集运行的进程。

此外,必须将分区的进程设计为仅处理其分配的数据集。分区架构必须与数据库设计和数据库分区策略紧密相关。请注意,数据库分区并不一定意味着数据库的物理分区,尽管在大多数情况下这是可取的。下图说明了分区方法:


分区过程

该体系结构应足够灵活,以允许动态配置分区数。应考虑自动和用户控制的配置。自动配置可以基于诸如输入文件大小和输入记录的数量之类的参数。

4.1分区方法选择分区方法必须根据具体情况进行。以下列表描述了一些可能的分区方法:

1.记录集的固定和均匀分解

这涉及将输入记录集分成偶数个部分(例如,10,其中每个部分恰好是整个记录集的十分之一)。然后,每个部分由批/提取应用程序的一个实例处理。

为了使用这种方法,需要预处理来分割记录集。此拆分的结果将是下限和上限放置编号,可用作批处理/提取应用程序的输入,以便将其处理限制为仅其部分。

预处理可能是一个很大的开销,因为它必须计算和确定记录集的每个部分的边界。

2.按键列分解

这涉及拆分由键列设置的输入记录,并将每个键的数据分配给批处理实例。为了实现这一点,列值可以是:

在选项1下,添加新值意味着手动重新配置批处理/提取以确保将新值添加到特定实例。

在选项2下,这可确保通过批处理作业的实例覆盖所有值。但是,一个实例处理的值的数量取决于列值的分布(0000-0999范围内可能有大量位置,1000-1999范围内可能很少)。在此选项下,数据范围应设计为考虑分区。

在这两个选项下,无法实现记录到批处理实例的最佳均匀分布。没有使用批处理实例数的动态配置。

3.按意见分解

这种方法基本上是由关键列分解,但在数据库级别上。它涉及将记录集分解为视图。批处理应用程序的每个实例在处理过程中都使用这些视图。分解是通过对数据进行分组来完成的。

使用此选项,必须将批处理应用程序的每个实例配置为命中特定视图(而不是主表)。此外,通过添加新数据值,必须将这组新数据包含在视图中。没有动态配置功能,因为实例数量的更改会导致视图发生更改。

4.增加处理指标

这涉及向输入表添加新列,该列充当指示符。作为预处理步骤,所有指标都标记为未处理。在批处理应用程序的记录提取阶段,读取记录的条件是该记录被标记为未处理,并且一旦读取它们(带锁定),它们就被标记为正在处理中。完成该记录后,指标将更新为完成或错误。批处理应用程序的许多实例可以在没有更改的情况下启动,因为附加列确保仅处理一次记录。在“完成时,指标被标记为完成”的顺序中的一两句话。)

使用此选项,表上的I / O会动态增加。在更新批处理应用程序的情况下,这种影响会减少,因为无论如何都必须进行写入。

5.将表提取到平面文件

这涉及将表提取到文件中。然后,可以将此文件拆分为多个段,并将其用作批处理实例的输入。

使用此选项,将表提取到文件中并将其拆分的额外开销可能会抵消多分区的影响。可以通过更改文件拆分脚本来实现动态配置。

6.使用哈希柱

此方案涉及向用于检索驱动程序记录的数据库表添加哈希列(键/索引)。此哈希列具有一个指示器,用于确定批处理应用程序的哪个实例处理此特定行。例如,如果要启动三个批处理实例,则指示符“A”标记要由实例1处理的行,“B”的指示符标记要由实例2处理的行,以及指示符“C” '标记了实例3处理的行。

然后,用于检索记录的过程将有一个附加WHERE子句来选择由特定指示符标记的所有行。此表中的插入将涉及添加标记字段,该字段将默认为其中一个实例(例如“A”)。

将使用简单的批处理应用程序来更新指示符,例如在不同实例之间重新分配负载。当添加了足够多的新行时,可以运行此批处理(除批处理窗口外的任何时间)以将新行重新分发到其他实例。

批处理应用程序的其他实例仅需要运行前面段落中所述的批处理应用程序,以重新分配指示符以使用新的实例数。

4.2数据库和应用程序设计原则

支持使用键列方法针对分区数据库表运行的多分区应用程序的体系结构应包括用于存储分区参数的中央分区存储库。这提供了灵活性并确保了可维护性。存储库通常由单个表组成,称为分区表。

存储在分区表中的信息是静态的,通常应由DBA维护。该表应包含多行分区应用程序的每个分区的一行信息。该表应包含程序ID代码,分区号(分区的逻辑ID),此分区的db键列的低值以及此分区的db键列的高值。

在程序启动时,id应该从体系结构(特别是从Control Processing Tasklet)将程序和分区号传递给应用程序。如果使用键列方法,则使用这些变量来读取分区表,以确定应用程序要处理的数据范围。此外,在整个处理过程中必须使用分区号:

4.3尽量减少死锁

当应用程序并行运行或分区时,可能会发生数据库资源争用和死锁。作为数据库设计的一部分,数据库设计团队尽可能地消除潜在的争用情况至关重要。

此外,开发人员必须确保数据库索引表的设计时考虑到死锁和性能。

管理或体系结构表中经常出现死锁或热点,例如日志表,控制表和锁定表。还应考虑到这些问题的影响。实际压力测试对于识别架构中可能存在的瓶颈至关重要。

为了最大限度地减少冲突对数据的影响,架构应在附加到数据库或遇到死锁时提供等待和重试间隔等服务。这意味着内置机制对某些数据库返回代码作出反应,而不是发出立即错误,等待预定的时间并重试数据库操作。

4.4参数传递和验证

分区架构应该对应用程序开发人员相对透明。该体系结构应执行与以分区模式运行应用程序相关的所有任务,包括:

验证应包括检查以确保:

如果数据库已分区,则可能需要进行一些额外的验证,以确保单个分区不跨越数据库分区。

此外,该体系结构应考虑分区的合并。关键问题包括:

上一篇 下一篇

猜你喜欢

热点阅读