使用案例:从数据库中读取1000万行[10列]并写入文件(csv格式).
将建议JdbcCursorItemReader和JdbcPagingItemReader中的哪个ItemReader实现?那是什么原因?
在上述用例中哪个表现更好(快)?
在单流程与多流程方法的情况下,选择会有所不同吗?
在使用TaskExecutor的多线程方法的情况下,哪一个会更好和简单?
Michael Mine.. 9
要处理这种数据,如果可能的话,你可能想要并行化它(如果输出文件需要保留输入的顺序,那么唯一阻止它的是).假设您要对您的处理进行并行化,那么您可以为此类用例提供两个主要选项(根据您提供的内容):
多线程步骤 - 这将处理每个线程的块,直到完成.这允许以非常简单的方式进行并行化(只需在步骤定义中添加TaskExecutor).有了这个,你就可以开箱即用,因为你需要在你提到的任何一个ItemReader上关闭状态持久性(有很多方法可以将数据库中的记录标记为已经处理过,等等).
分区 - 这会将输入数据分解为由并行的步骤实例(主/从配置)处理的分区.分区可以通过线程(通过TaskExecutor)在本地执行,也可以通过远程分区远程执行.在任何一种情况下,您都可以通过并行化获得可重启性(每个步骤都处理它自己的数据,因此从分区到分区没有踩到状态).
我与Spring Batch并行处理数据.具体来说,我提供的示例是远程分区作业.您可以在此处查看:https://www.youtube.com/watch?v = CYTj5YT7CZU
针对您的具体问题:
将建议JdbcCursorItemReader和JdbcPagingItemReader中的哪个ItemReader实现?那是什么原因? - 可以调整这两个选项中的任何一个以满足许多性能需求.这实际上取决于您正在使用的数据库,可用的驱动程序选项以及您可以支持的处理模型.另一个考虑因素是,您需要重新启动吗?
在上述用例中哪个表现更好(快)? - 再次取决于您选择的处理模型.
在单流程与多流程方法的情况下,选择会有所不同吗? - 这比Spring Batch可以处理的更多地管理作业.问题是,您是要管理作业外部的分区(将数据描述作为参数传递给作业)还是希望作业管理它(通过分区).
在使用TaskExecutor的多线程方法的情况下,哪一个会更好和简单? - 我不会否认远程分区会增加本地分区和多线程步骤所没有的复杂程度.
我将从基本步骤定义开始.然后尝试多线程步骤.如果这不符合您的需求,则转到本地分区,最后根据需要进行远程分区.请记住,Spring Batch旨在使这种进展尽可能轻松.只需配置更新,您就可以从常规步骤转到多线程步骤.要进行分区,您需要添加一个新类(Partitioner实现)和一些配置更新.
最后一点说明.其中大部分讨论了并行处理这些数据.Spring Batch的FlatFileItemWriter 不是线程安全的.您最好的选择是并行写入多个文件,然后如果速度是您的头号问题则将它们聚合在一起.
要处理这种数据,如果可能的话,你可能想要并行化它(如果输出文件需要保留输入的顺序,那么唯一阻止它的是).假设您要对您的处理进行并行化,那么您可以为此类用例提供两个主要选项(根据您提供的内容):
多线程步骤 - 这将处理每个线程的块,直到完成.这允许以非常简单的方式进行并行化(只需在步骤定义中添加TaskExecutor).有了这个,你就可以开箱即用,因为你需要在你提到的任何一个ItemReader上关闭状态持久性(有很多方法可以将数据库中的记录标记为已经处理过,等等).
分区 - 这会将输入数据分解为由并行的步骤实例(主/从配置)处理的分区.分区可以通过线程(通过TaskExecutor)在本地执行,也可以通过远程分区远程执行.在任何一种情况下,您都可以通过并行化获得可重启性(每个步骤都处理它自己的数据,因此从分区到分区没有踩到状态).
我与Spring Batch并行处理数据.具体来说,我提供的示例是远程分区作业.您可以在此处查看:https://www.youtube.com/watch?v = CYTj5YT7CZU
针对您的具体问题:
将建议JdbcCursorItemReader和JdbcPagingItemReader中的哪个ItemReader实现?那是什么原因? - 可以调整这两个选项中的任何一个以满足许多性能需求.这实际上取决于您正在使用的数据库,可用的驱动程序选项以及您可以支持的处理模型.另一个考虑因素是,您需要重新启动吗?
在上述用例中哪个表现更好(快)? - 再次取决于您选择的处理模型.
在单流程与多流程方法的情况下,选择会有所不同吗? - 这比Spring Batch可以处理的更多地管理作业.问题是,您是要管理作业外部的分区(将数据描述作为参数传递给作业)还是希望作业管理它(通过分区).
在使用TaskExecutor的多线程方法的情况下,哪一个会更好和简单? - 我不会否认远程分区会增加本地分区和多线程步骤所没有的复杂程度.
我将从基本步骤定义开始.然后尝试多线程步骤.如果这不符合您的需求,则转到本地分区,最后根据需要进行远程分区.请记住,Spring Batch旨在使这种进展尽可能轻松.只需配置更新,您就可以从常规步骤转到多线程步骤.要进行分区,您需要添加一个新类(Partitioner实现)和一些配置更新.
最后一点说明.其中大部分讨论了并行处理这些数据.Spring Batch的FlatFileItemWriter 不是线程安全的.您最好的选择是并行写入多个文件,然后如果速度是您的头号问题则将它们聚合在一起.
您应该对此进行分析以便做出选择.在简单的JDBC中,我会从以下内容开始:
用ResultSet.TYPE_FORWARD_ONLY
和准备陈述ResultSet.CONCUR_READ_ONLY
.除非您使用这两个游标,否则几个JDBC驱动程序会"模拟"客户端中的游标,而对于大型结果集,您不希望这样,因为它可能会引导您,OutOfMemoryError
因为您的JDBC驱动程序正在缓冲内存中的整个数据集.通过使用这些选项,您可以增加获得服务器端游标的机会,并将结果"流式传输"到您的位置,这就是您想要的大型结果集.请注意,某些JDBC驱动程序始终在客户端"模拟"游标,因此此提示可能对您的特定DBMS无用.
设置合理的提取大小,以最大限度地减少网络往返的影响.50-100通常是分析的良好起始值.由于提取大小是提示,这对您的特定DBMS也可能没用.
JdbcCursorItemReader
似乎涵盖了这两个方面,但正如之前所说的那样,并不能保证在所有DBMS中都能提供最佳性能,所以我会从那开始,然后,如果性能不足,请尝试JdbcPagingItemReader
.
JdbcCursorItemReader
除非您有非常严格的性能要求,否则我认为对您的数据集大小进行简单处理并不会很慢.如果你真的需要并行化使用JdbcPagingItemReader
可能会更容易,但这两者的界面非常相似,所以我不会指望它.
无论如何,个人资料.