Performance 如何在SpringBatch中提高FlatFileItemReader的性能?

Performance 如何在SpringBatch中提高FlatFileItemReader的性能?,performance,batch-processing,spring-batch,Performance,Batch Processing,Spring Batch,我正在编写SpringBatch,它从平面文件读取数据,进行少量处理,并将摘要写入输出文件。与reader相比,我的处理器和编写器相对更快。我正在使用FlatFileItemReader,并尝试了从50-1000开始的大范围提交间隔。我的批处理作业必须以更快的速度处理1000万条记录。请让我知道如何提高FlatFileItemReader的速度。粘贴到我的配置文件和映射器类下面,读取字段集并将值设置为POJO bean。先谢谢你 BatchFileConfig.xml <!-- Flat

我正在编写SpringBatch,它从平面文件读取数据,进行少量处理,并将摘要写入输出文件。与reader相比,我的处理器和编写器相对更快。我正在使用FlatFileItemReader,并尝试了从50-1000开始的大范围提交间隔。我的批处理作业必须以更快的速度处理1000万条记录。请让我知道如何提高FlatFileItemReader的速度。粘贴到我的配置文件和映射器类下面,读取字段集并将值设置为POJO bean。先谢谢你

BatchFileConfig.xml

<!-- Flat File Item Reader and its dependency configuration starts here -->
<bean id="flatFileReader" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="classpath:flatfiles/input_10KFile.txt" />
    <property name="encoding" value="UTF-8" />
    <property name="linesToSkip" value="1" />
    <property name="lineMapper">
        <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
            <property name="lineTokenizer">
                <bean
                    class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                    <property name="names"
                        value="var1,var2,var3,var4,var5,var6" />
                    <property name="delimiter" value="&#009;" />
                    <property name="strict" value="false" />
                </bean>
            </property>
            <property name="fieldSetMapper" ref="companyMapper">
            </property>
        </bean>
    </property>
</bean>

我认为你不能把这个过程加快很多:/
CompanyMapper
已经是一个自定义实现,因此您可以考虑:

  • 编写一个自定义的
    LineTokinizer
    +
    FieldSet
    耦合,以避免大量(有用的)检查和错误处理
  • 编写一个自定义的
    BufferedReaderFactory
    来创建自己的
    BufferedReader
    实现,它封装了一个自定义的(更快的)
    InputStream
    实现(请在谷歌上查找)

  • 我想既然你说的是1000万数据,我建议你使用SpringBatchs的伸缩特性。我最近执行了向db发布500-800万数据的操作。为了获得性能,我使用文件通道(快速读/写)将文件拆分为100万,然后使用分区,在从属步骤中使用单独的线程读取100万个文件。虽然对于小数据,您可能无法获得良好的性能差异,但对于这样数量级的数据,性能差异是巨大的。同时,正如@M.Deinum所建议的,尝试删除日志记录。它肯定会慢下来

    你好,提高阅读器速度的最终方法是在内存中读取文件。只要你有足够的内存,你就可以立即阅读。如果你不知道,你可以尽可能多地阅读。一旦你把它放在内存中,你就需要实现你的“资源”,它将指向物理文件,指向你文件的内存内容。如果现代硬盘速度超过每秒500毫克,即使是巨大的文件也会在内存中完全读取几秒钟

    一旦它在内存中,所有操作的运行速度都将提高一个数量级。如果您愿意,这也将为您提供线性扩展功能


    如果您的内容在内存中,您可以轻松地并行工作,而不会在硬盘周围形成瓶颈。

    发布配置和一些代码。很难说,如果您在进行切换,可能您正在进行大量转换(转换为对象非常耗时),这也会降低性能。您的
    公司映射是什么?你能在你的工作配置上多发布一点吗?谢谢你的回复,迪纳姆先生。你能在这里看到任何作用域吗?
    System.currentTimeMillis()
    相对较慢,不会在高性能代码中添加这一点。日志记录也是如此,这取决于您的日志记录位置,可能会很慢(基本上,写入
    System.out
    非常慢)。日志还(始终)执行
    String.concat
    。我会先试着把它们去掉,看看会发生什么。我也会对你认为慢的东西感兴趣(你的过程需要多长时间)。您可能还想在代码中附加一个概要文件(例如JProfiler),并查看所有这些类中发生了什么。
     public Company mapFieldSet(FieldSet fieldSet) throws BindException {
        logger.warn("Start time is "+System.currentTimeMillis());
        if (fieldSet != null) {
        Company company = new Company();
        company.setvar1(fieldSet.readString("var1"));
        company.setvar2(fieldSet.readInt("var2"));
        company.setvar3(fieldSet.readString("var3"));
        company.setvar4(fieldSet.readInt("var4"));
        company.setvar5(fieldSet.readInt("var5"));
        company.setvar6(fieldSet.readInt("var6"));
        return company;
        }
        return null;
    }