7

我们有一个令人尴尬的并行问题——我们运行单个程序的大量实例,每个实例具有不同的数据集;我们只需将应用程序多次提交到批处理队列,每次使用不同的参数即可。

然而,由于有大量工作,并非所有工作都完成。队列中似乎没有问题 - 所有作业都已启动。

问题似乎在于,在运行大量应用程序实例的情况下,许多作业大致同时完成,因此都试图几乎同时将它们的数据写入并行文件系统。

然后问题似乎是程序无法写入文件系统并以某种方式崩溃,或者只是坐在那里等待写入并且批处理队列系统在等待太久后终止了作业。(从我收集到的问题来看,大多数未能完成的工作,如果不是全部,不要留下核心文件)

安排磁盘写入以避免此问题的最佳方法是什么?我提到我们的程序是令人尴尬的并行,以强调每个进程都不知道其他进程的事实——它们不能相互交谈以以某种方式安排他们的写入。

虽然我有该程序的源代码,但我们希望解决问题而无需尽可能修改它,因为我们不维护或开发它(加上大多数评论都是意大利语)。

我对这个问题有一些想法:

  1. 每个作业首先写入节点的本地(暂存)磁盘。然后我们可以运行另一个作业,它不时检查哪些作业已完成并将文件从本地磁盘移动到并行文件系统。
  2. 在主/从系统中围绕程序使用 MPI 包装器,其中主管理作业队列并将这些作业分配给每个从属;并且从属包装器运行应用程序并捕获异常(我可以可靠地为 C++ 或 Java 中的文件系统超时执行此操作吗?),并将消息发送回主控器以重新运行作业

与此同时,我需要向我的主管询问有关错误本身的更多信息——我个人从未遇到过它,但我还没有必要将程序用于大量数据集。

如果有用:我们在 HPC 系统上使用 SGE(Sun GridEngine)批处理队列系统运行 Solaris。文件系统是 NFS4,存储服务器也运行 Solaris。HPC 节点和存储服务器通过光纤通道链路进行通信。

4

3 回答 3

7

大多数并行文件系统,尤其是超级计算中心的那些,都是针对 HPC 应用程序的,而不是串行农场类型的东西。因此,它们针对带宽进行了精心优化,而不是针对 IOP(每秒 I/O 操作)——也就是说,它们针对的是编写少量庞大文件的大型(1000 多个进程)作业,而不是数以千计的小文件输出 octillions 的微小文件的作业。用户可以很容易地在他们的桌面上运行运行良好(ish)的东西,并且天真地扩展到数百个同时作业以使 IOP 系统挨饿,挂起他们的作业以及通常在同一系统上的其他作业。

您可以在这里做的主要事情是聚合,聚合,聚合。最好能告诉我们您在哪里运行,以便我们获得有关系统的更多信息。但是一些行之有效的策略:

  1. 如果每个作业要输出许多文件,请更改输出策略,以便每个作业写出一个包含所有其他文件的文件。如果您有本地 ramdisk,您可以做一些简单的事情,例如将它们写入 ramdisk,然后将它们 tar-gzing 到真实的文件系统。
  2. 用二进制而不是ASCII写。大数据永远不会进入 ascii。二进制格式的写入速度大约快 10 倍,而且稍微小一些,并且您可以一次写入大块而不是循环中的几个数字,这会导致:
  3. 大写比小写好。每个 IO 操作都是文件系统必须做的事情。少写大写,而不是循环写小写。
  4. 同样,不要以需要您四处寻找以在不同时间写入文件的不同部分的格式写入。搜索缓慢且无用。
  5. 如果您在一个节点上运行许多作业,您可以使用与上述相同的 ramdisk 技巧(或本地磁盘)来压缩所有作业的输出并将它们一次全部发送到并行文件系统。

上述建议将有利于您的代码在任何地方的 I/O 性能,而不仅仅是在并行文件系统上。IO 到处都很慢,你在内存中可以做的越多,你执行的实际 IO 操作越少,它就会越快。有些系统可能比其他系统更敏感,因此您可能不会在笔记本电脑上注意到它,但它会有所帮助。

同样,使用较少的大文件而不是许多小文件将加速从目录列表到文件系统备份的所有内容;周围都很好。

于 2011-04-11T20:22:49.630 回答
2

很难确定您是否不知道究竟是什么导致了崩溃。如果您认为这是与文件系统性能有关的错误,您可以尝试分布式文件系统:http: //hadoop.apache.org/common/docs/r0.20.0/hdfs_user_guide.html

如果你想实现主/从系统,也许 Hadoop 可以是答案。

但首先我会尝试找出导致崩溃的原因......

于 2011-04-11T20:11:17.090 回答
1

操作系统在资源耗尽时并不总是表现良好。有时他们只是简单地中止请求操作系统无法提供的第一个资源单元的进程。许多操作系统都有文件句柄资源限制(我认为 Windows 有几千个句柄资源,您可以在像您这样的情况下遇到这些资源),并且找不到空闲句柄通常意味着操作系统对请求进程做了坏事。

一个需要更改程序的简单解决方案是同意您的许多工作中不能有超过 N 个可以同时编写。您需要一个所有作业都可以看到的共享信号量;大多数操作系统都会为您提供一个功能,通常作为命名资源(!)。在启动任何作业之前将信号量初始化为 N。让每个写入作业在作业即将写入时从信号量获取一个资源单元,并在完成时释放该资源单元。完成此操作的代码量应该是插入到高度并行应用程序中的几行代码。然后你调整 N 直到你不再有问题。N==1 肯定会解决它,而且你可能会做得比这更好。

于 2011-04-11T20:57:18.120 回答