0

我每次必须定期在 1 个文件夹中转换大量 XML 文件(最少 100K)(基本上,从解压缩的输入数据集中),我想学习如何以最有效的方式做到这一点。我的技术堆栈由 XLT 和 Saxon XSLT Java 库组成,它们是从 Bash 脚本调用的。它运行在具有 8 个内核的 Ubuntu 服务器和具有 64Gb 内存的 SSD RAID 上。请记住,我很好地处理了 XSLT,但我仍在学习 Bash 以及如何为此类任务正确分配负载(当时 Java 也几乎只是一个词)。

之前创建了一个关于这个问题的帖子,因为我的方法似乎非常低效并且实际上需要帮助才能正常运行(参见这个SOF 帖子。后来有很多评论,以不同的方式提出这个问题是有意义的,因此这篇文章。有人向我提出了几种解决方案,其中一种目前比我的要好得多,但它仍然可以更加优雅和高效。

现在,我正在运行这个:

printf -- '-s:%s\0' input/*.xml | xargs -P 600 -n 1 -0 java -jar saxon9he.jar -xsl:some-xslt-sheet.xsl

我根据之前的一些测试设置了 600 个进程。更高只会引发 Java 的内存错误。但它现在只使用 30 到 40Gb 的 RAM(尽管所有 8 个内核都处于 100% 状态)。

简而言之,这是我迄今为止的所有建议/方法:

  1. 在子文件夹之间拆分整个 XML 文件(例如,包含每个 5K 文件),并将其用作在每个子文件夹的并行转换脚本中运行的一种方式
  2. 专门使用Saxon- EE (允许多线程执行)和collection()函数来解析 XML 文件
  3. 设置任务数量较少的 Java 环境,或减少每个进程的内存
  4. 指定 Saxon 是否与 XSLT 表兼容 libxml/libxslt(不是仅适用于 XSLT1.0 吗?)
  5. 使用专门的外壳,例如xmlsh

我可以处理解决方案#2,它应该直接启用控制循环并仅加载一次JVM;#1 似乎更笨拙,我仍然需要在 Bash 中改进(负载分布和性能,处理相对/绝对路径);#3、#4 和 #5 对我来说是全新的,我可能需要更多解释来了解如何解决这个问题。

任何投入将不胜感激。

4

2 回答 2

0

“可能的最有效方式”要求很多,通常不是一个合理的目标。例如,我怀疑您是否准备好花费 6 个月的时间将流程效率提高 3%。您正在寻找的是一种满足性能目标并且可以以最小的努力实施的方法。而“效率”本身就引发了关于你的指标是什么的问题。

我非常有信心我所建议的设计,通过使用 collection() 和 xsl:result-document(在 Saxon-EE 中都并行化)处理所有文件的单个转换能够提供良好的结果,并且很可能与我会考虑的唯一其他方法相比,工作量要少得多,即编写一个 Java 应用程序来保存“控制逻辑”:虽然如果你擅长编写多线程 Java 应用程序,那么你可能会得到它利用您对工作负载的了解来加快速度。

于 2017-03-31T15:45:52.877 回答
0

尝试使用. xsltproc_ libxslt它可以将多个 xml 文件作为参数。要这样调用它,您需要先创建一个输出目录。尝试这样称呼它:

mkdir output
xsltproc -o output/ some-xslt-sheet.xsl input/*.xml
于 2017-04-02T00:40:38.017 回答