1

我们开发了一个 spring 批处理应用程序,其中有两个流程。1. 前进 2. 后退。我们只使用文件读/写不涉及数据库。

  1. Forward Scenario : 输入文件将有 22 个字段的记录。通过进行序列号生成和添加少量填充字段等操作,将 22 个字段转换为 32 个字段。根据国家代码,输出将被分成最多 3 个。每个块将有 250K 记录。(如果记录以百万为单位,将为同一国家/地区生成多个文件)。

    800 万条记录耗时 36 分钟。

    800 万条记录将在一个文件中。

    我们正在使用我们正在使用的弹簧批处理线程 1000 个线程。

  2. 后向流:输入文件的每条记录将有 82 个字段。这82个字段要转换成86条记录。这两个字段将被添加在这两个字段之间,这两个字段取自正向流输入文件。其他字段只是简单地复制和粘贴。错误记录也要写入错误文件。错误记录只不过是前向流的实际输入记录。为了跟踪,我们将序列号和实际记录保存在一个文件中,这是在前向流本身中完成的。我们正在反向流中获取持久文件并比较序列号,如果缺少任何内容,那么我们将通过键值对写入错误记录。这个过程是在回流完成后完成的。

    输入文件的最大大小为 250K。

    800 万条记录需要 1 小时 8 分钟,这太糟糕了。在此流程中将有 32 个文件(每个 250K)供输入。向后没有使用线程。我不知道线程使用情况如何。我试过了,但这个过程挂了。

服务器配置:

  • 12 个 CPU 和 64 GB Linux 服务器。

    由于我们有 12 个 CPU/64GB RAM,你们能否在这方面帮助提高性能。

4

1 回答 1

0

您已经在使用 1000 个线程,这是一个非常高的数字。我已经对 spring 批处理作业进行了微调,这就是我所做的 1. 减少网络流量 - 尝试减少每个进程中对数据库或文件系统的调用次数。您能否一次获得所有可能的信息并将其保存在内存中以供线程使用?我使用 org.apache.commons.collections.map.MultiKeyMap 来存储和检索数据。例如,在您的情况下,您需要序列号比较。因此,在开始该过程之前,将所有序列号放入一张地图中。您可以将 ID(如果不是太多)存储到步骤执行上下文中。

  1. 写得少——把你需要写的所有信息保存一段时间,然后在最后写。

  2. 将进程结束时未使用的对象设置为 null 以加快 GC

  3. 通过 VisualVm 或 Jconsole 检查您的 GC 频率。当您的进程正在运行时,您应该会看到频繁的 GC 发生,这意味着正在创建对象并收集垃圾。如果您的内存图不断增加,则说明有问题。

于 2012-09-12T14:07:34.240 回答