spring 处理 50k 文件的批处理设计建议
spring batch design advice for processing 50k files
我们每天有超过 5 万个文件需要处理。为此,我们开发了设计如
的 POC 应用程序
- 轮询应用程序从 ftp 区域连续选取文件。
- 验证该文件并在数据库中创建元数据 table。
- 另一个轮询器从数据库中挑选 10-20 个文件(仅文件 ID 和状态)并将其作为消息传递给从属应用程序
- 从属应用程序获取消息并启动 spring 批处理作业,该作业正在读取数据,在处理器中进行业务验证并将验证数据写入 db/another 文件。
我们为此 POC 使用了 spring 集成和 spring 批处理技术
在 slaves 中启动 spring 批处理作业或直接实现读取、处理和写入逻辑作为计划 java 或 spring bean 对象是个好主意吗?
需要一些关于启动这项工作的见解,其中从可以有 10-25 个 MDP(spring 消息驱动的 pojo)并且每个 MDP 都在启动一个工作。
注意:每个文件最多有 30 - 40,000 条记录
通常,使用 SpringIntegration 和 SpringBatch 来完成此类任务是个好主意。这就是他们的目的。
关于 SpringBatch,您可以开箱即用地进行整个重试、跳过和重新启动处理。此外,您拥有所有这些针对批量操作进行了优化的读取器和写入器。这非常有效,您只需专注于编写适当的映射器和类似的东西。
如果您想使用普通 java 或 spring bean 对象,您最终可能会自己开发此类基础结构代码...包括。所有需要的测试等工作。
关于您的设计:
除了验证和创建元数据条目外,您还可以考虑将条目直接加载到数据库中 table。如果出现问题,这会给你更好的 "transactional" 控制。您的加载作业可能如下所示:
第一步:
在元数据 table 中创建条目的任务小程序,其列如
- FILE_TO_PROCESS: XY.txt
- STATE: START_LOADING
- DATE: ...
- ATTEMPT: ... first attempt
步骤二:
读取并验证文件的每一行并将其存储在数据中table
- DATA: ........
- STATE:
- FK_META_TABLE: ForeignKey to meta table
第三步:
使用状态 LOAD_completed
更新元 table
-STATE : LOAD_COMPLETED
因此,一旦您的元table 条目获得状态 LOAD_COMPLETED,您就知道文件的所有条目都已通过验证并准备好进行进一步处理。
如果出现问题,您只需修复文件并重新加载即可。
然后,为了进一步处理,您可以让作业定期轮询并检查数据库中是否有新数据需要处理。如果在上一期间加载了多个文件,则只需处理所有准备就绪的文件即可。
您甚至可以让多个从属进程不时进行轮询。只需读取元数据状态的更新 table 或使用乐观锁定方法来防止多个从属尝试处理相同的条目。
使用此解决方案,您不需要消息基础结构,您仍然可以毫无问题地扩展整个应用程序。
我们每天有超过 5 万个文件需要处理。为此,我们开发了设计如
的 POC 应用程序- 轮询应用程序从 ftp 区域连续选取文件。
- 验证该文件并在数据库中创建元数据 table。
- 另一个轮询器从数据库中挑选 10-20 个文件(仅文件 ID 和状态)并将其作为消息传递给从属应用程序
- 从属应用程序获取消息并启动 spring 批处理作业,该作业正在读取数据,在处理器中进行业务验证并将验证数据写入 db/another 文件。
我们为此 POC 使用了 spring 集成和 spring 批处理技术
在 slaves 中启动 spring 批处理作业或直接实现读取、处理和写入逻辑作为计划 java 或 spring bean 对象是个好主意吗?
需要一些关于启动这项工作的见解,其中从可以有 10-25 个 MDP(spring 消息驱动的 pojo)并且每个 MDP 都在启动一个工作。
注意:每个文件最多有 30 - 40,000 条记录
通常,使用 SpringIntegration 和 SpringBatch 来完成此类任务是个好主意。这就是他们的目的。
关于 SpringBatch,您可以开箱即用地进行整个重试、跳过和重新启动处理。此外,您拥有所有这些针对批量操作进行了优化的读取器和写入器。这非常有效,您只需专注于编写适当的映射器和类似的东西。
如果您想使用普通 java 或 spring bean 对象,您最终可能会自己开发此类基础结构代码...包括。所有需要的测试等工作。
关于您的设计:
除了验证和创建元数据条目外,您还可以考虑将条目直接加载到数据库中 table。如果出现问题,这会给你更好的 "transactional" 控制。您的加载作业可能如下所示:
第一步:
在元数据 table 中创建条目的任务小程序,其列如
- FILE_TO_PROCESS: XY.txt
- STATE: START_LOADING
- DATE: ...
- ATTEMPT: ... first attempt
步骤二:
读取并验证文件的每一行并将其存储在数据中table
- DATA: ........
- STATE:
- FK_META_TABLE: ForeignKey to meta table
第三步:
使用状态 LOAD_completed
-STATE : LOAD_COMPLETED
因此,一旦您的元table 条目获得状态 LOAD_COMPLETED,您就知道文件的所有条目都已通过验证并准备好进行进一步处理。 如果出现问题,您只需修复文件并重新加载即可。
然后,为了进一步处理,您可以让作业定期轮询并检查数据库中是否有新数据需要处理。如果在上一期间加载了多个文件,则只需处理所有准备就绪的文件即可。 您甚至可以让多个从属进程不时进行轮询。只需读取元数据状态的更新 table 或使用乐观锁定方法来防止多个从属尝试处理相同的条目。
使用此解决方案,您不需要消息基础结构,您仍然可以毫无问题地扩展整个应用程序。