【问题标题】:Apache POI - is caching workbook best way to reuse?Apache POI - 缓存工作簿是重用的最佳方式吗?
【发布时间】:2015-12-31 23:57:36
【问题描述】:

几年来,我们一直在生产环境中使用 Apache POI,并取得了不错的效果。当前版本为 3.11。我们只使用 HSSF(根据我们的测试比 XSSF 更快,而且我们可以不用 XLSX。)

我们目前在内存中保留了一个“同步工作簿运行程序”的缓存地图,大约有 70 个左右。将每个 XLS 想象成一个产品,映射键告诉我们使用哪一个。我们在启动时加载缓存,因此我们永远不会实时读取文件。

我们的同步跑步者大致是这样的:

public class PoiProcessorSynchronized {
  private Workbook workbook;
  public synchronized Map<String, Object> process(Request request) {
    engine.process(workbook, request); //request has input/output params
  }
}

这使得性能非常好(过去 24 小时平均 112 毫秒的 27k 请求)一些工作表很慢,一些工作表很快。我们在处理之间手动重置输入到工作表中,以确保工作表在两次使用之间保持清洁。

保持工作表处理同步是为了防止计算错误。我们最初确实看到了一些计算错误,而没有控制对工作表的访问。自从我们这样做以来,它一直很稳固。

我关心的一些问题:

  1. 对于每台服务器,每个 XLS 一次只能处理一个请求。我想我们可以通过使用某种处理器池来解决这个问题
  2. 工作簿的内存相对较大。如果我们继续将 XLS 添加到缓存中,我们必须添加越来越多的内存。

还有其他人尝试做类似的事情吗?该方法目前有效,但感觉应该有更好的方法。

我们是否可以缓存其他工作簿的内容?还是序列化一些东西?

有没有人通过工作簿成功处理大量数据而不同步它们?如果有怎么办?

【问题讨论】:

  • Apache POI 总体上是线程安全的,但工作簿及其内容不是。您可以让不同的线程非常愉快地在自己的工作簿上工作,但您必须只有一个线程处理一个给定的打开工作簿
  • @Gagravarr 我们绝对可以并且确实可以通过上述方式实现这一目标。从您的角度来看,Workbook 是正确的缓存对象吗?
  • @javatestcase 我们做的基本相同(使用 XSSF 而不是 HSSF)。我们正在使用 org.apache.commons.pool.impl.GenericKeyedObjectPool 进行池化。
  • @Kai 谢谢,我将尝试实现它。

标签: java apache-poi


【解决方案1】:

在库级别,Apache POI 是线程安全的。在工作簿级别(+sheet/row/cell/etc 级别),Apache POI 不是线程安全的。给定的工作簿一次只能由一个线程处理。如果您有多个线程并行工作,它们必须有自己的工作簿来处理。不支持处理同一工作簿的两个线程(包括处理同一工作簿中的不同工作表)。

总的来说,加载 .xls 文件相当快。使用File rather than an InputStream if you can 可以稍微降低内存并加快加载速度。请参阅memory and performance FAQ for some guides。确保您使用最新版本的 Apache POI for bug fixes and improvements

对于您的具体情况,最流行的工作簿的某种缓存可能效果很好。也许只适用于较大的流行工作簿,而小型工作簿总是按需加载。

否则,请尝试进行一些分析,看看 POI 是否在某个地方对您的某些文件做了太多工作。那么report that and work to get it fixed,性能提升总是受到项目的欢迎!

【讨论】:

    【解决方案2】:

    这个问题的答案完全取决于 POI 本身是否以完全线程安全的方式实现。

    鉴于 POI 网站上的文档或常见问题解答中的任何地方都没有提到并发和线程安全,您必须假设它不是线程安全的。

    快速查看POI 3.5 HSSFWorkbook code at DocJar 发现没有同步关键字,并且使用了简单的非同步集合......所以不,它不是线程安全的。

    因此,您的同步方法可能是您能做的最好的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-10
      • 2021-11-22
      • 2011-05-29
      • 1970-01-01
      相关资源
      最近更新 更多