如何高效地并行运行大量文件的XSLT转换?

问题描述:

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

以前创建有关此问题的帖子,因为我的做法显得很低效,实际上是需要帮助的正常运行(见本SOF post。很多评论后来,这是有道理的提出不同的问题,因此这篇文章。我提出了几种解决方案,其中一种解决方案比我的解决方案要好得多,但它仍然可能更加优雅和高效。现在

,我运行以下命令:

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文件),并使用此作为一种并行转换脚本与collection()功能运行每个子文件夹
  2. 使用专门的Saxon-EE library(允许 多线程执行)来解析XML文件
  3. 套装Java环境具有较低的任务数,或降低 每个进程
  4. 指定撒克逊关于如果XSLT张是兼容的内存 libxml/libxslt(是不是只为XSLT1.0?)
  5. 使用一个专门的外壳如xmlsh

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

任何输入将不胜感激。

+0

这是不难做到的XSLT转换在Java和具有相同JVM变换数以千计的文件,你可以得到编译XSLT文件只有一次的利益,并利用执行人来以受控的方式并行处理它们。这需要相当一些编码,而且“X分开组”可能会更简单。 –

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

我非常有信心,我提出的设计,使用collection()和xsl:result-document(它们都在Saxon-EE中并行化)处理所有文件的单个转换能够给出良好的结果,并且可能比我考虑的唯一其他方法要少很多,那就是编写一个Java应用程序来保存“控制逻辑”:尽管如果你擅长编写多线程Java应用程序,那么你可以通过利用你对工作负载的知识,可能会让它变得更快一些。

+0

正如你所说的,使用EE版本应该是非常有帮助的,非常感谢。但是,编写Java应用程序不属于我的技能组合,所以我会通过。但是,只要服务器完成第一次运行,我就会尝试你的方法。对于我可能无法遵循的最终效率改进方法而言,你是对的,但我仍然希望在坚实的基础上建立自己的知识,而不是为了获得我最终没有真正掌握的东西。 –

尝试从libxslt使用xsltproc command line tool。它可以将多个xml文件作为参数。要这样调用它,你需要先创建一个输出目录。尝试调用它像这样:

mkdir output 
xsltproc -o output/ some-xslt-sheet.xsl input/*.xml 
+0

感谢你们,我也会对它进行测试,并比较各种表现。 –