【问题标题】:How to increase the performance of FlatFileItemReader in SpringBatch?Spring Batch 中如何提高 FlatFileItemReader 的性能?
【发布时间】:2013-12-13 03:55:16
【问题描述】:

我正在编写从平面文件中读取的 Spring Batch,做很少的处理并将摘要写入输出文件。与阅读器相比,我的处理器和编写器相对更快。我正在使用 FlatFileItemReader 并尝试使用从 50-1000 开始的各种提交间隔。我的批处理作业必须以更快的速度处理 1000 万条记录。请让我知道提高 FlatFileItemReader 速度的方法。粘贴在我的配置文件下面,我的 Mapper 类读取字段集并将值设置为 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.java

 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;
}

【问题讨论】:

  • 发布配置和一些代码。很难说,如果你正在做切换,也许你正在做很多转换(转换为一个对象很耗时),这也会降低性能。
  • 你的companyMapper 是什么?你能多发布一些关于你的工作配置的信息吗?
  • 感谢您的回复 M. Deinum 。你能在这里看到任何范围吗?
  • System.currentTimeMillis() 相对较慢,不会在高性能代码中添加它。日志记录也是如此,具体取决于您记录的位置,这可能会很慢(基本上写到System.out 真的很慢。)。日志记录也(总是)执行String.concat。会尝试先删除那些,看看会发生什么。
  • 也对你认为慢的东西感兴趣(你的过程需要多长时间)。您可能还想将配置文件(例如 JProfiler)附加到您的代码中,并查看所有这些类中发生了什么。

标签: performance batch-processing spring-batch


【解决方案1】:

我认为你不能加快进程很多:/ CompanyMapper 已经是自定义实现了,你可以这么想:

  1. 编写自定义LineTokinizer + FieldSet 对避免大量(有用的)检查和错误处理
  2. 编写一个自定义 BufferedReaderFactory 来创建您自己的 BufferedReader 实现,该实现封装了一个自定义(并且更快)InputStream 实现(在 Google 上查找)

【讨论】:

    【解决方案2】:

    我想既然你说的是 1000 万个数据,我建议你使用 spring 批量缩放功能。我最近实现了将 5-8 百万个数据发布到数据库。为了获得性能,我使用文件通道(快速读/写)将文件拆分为 100 万个,然后使用分区,我在从属步骤中使用单独的线程读取每个 100 万个文件。尽管对于小数据,您可能无法获得良好的性能差异,但对于这种数量级的数据会产生巨大的差异。也正如@M 所建议的那样。 Deinum 尝试删除日志记录。它肯定会慢下来。

    【讨论】:

      【解决方案3】:

      您好,加快阅读器速度的最终方法是在内存中读取文件。只要您有足够的内存,您就可以一次读取它。如果你不这样做,你可以尽可能多地阅读。一旦你把它放在内存中,你需要实现你的“资源”,而不是物理文件将指向你文件的内存内容。假设现代硬盘速度超过每秒 500mg,即使是巨大的文件也将在几秒钟内完全在内存中读取。

      一旦它在内存中,您的所有操作都会运行得更快一个数量级。如果您愿意,这还将为您提供线性缩放功能。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-17
        • 1970-01-01
        • 2019-01-26
        • 2020-02-03
        • 1970-01-01
        相关资源
        最近更新 更多