在 UT Grid 项目中,有一个叫做 GridShell 的工具被设计用来将网格的概念集成到命令行 shell 环境中,它目前还正在开发之中。GridShell 对 TENEX C Shell(TCSH)和 Bourne Again Shell(BASH)的语法进行了扩充,添加了一些新的特性,使得用户可以:
- 透明地将作业提交给分布式的远程管理的网格资源。
- 通过 GridFTP 将标准输出重定向到远程存储上。
- 利用使用内置任务间通信和同步原语的脚本进行并行执行。
下图展示了 GridShell 如何适合本地环境。
图 1. GridShell 在本地安装中的位置
在本文中,我将介绍为什么我们要开发 GridShell,并从较高层次上对这些扩展进行介绍。熟悉 TSCH 和 BASH 的用户应该可以使用本文作为起点,使用这些扩展来编写自己的脚本。这些脚本将可以让您对程序在网格上的执行进行协调。
首先,让我们将注意力转移到开发 GridShell 的动机上。
GridShell 的目标是隐藏使用分布式和网格计算功能所带来的复杂性。GridShell 通过充分利用大家熟悉的命令行环境来实现这种功能。
命令行 shell 提供了一个环境来调用和组合命令,并且可以通过脚本来构建复杂的问题解决工具。命令行 shell 在 UNIX® 用户之间非常流行,原因如下:
- 可移植性和透明性 —— shell 提供了一个可移植的体系架构透明的执行环境。例如,可以保证 Intel® Pentium® 4 处理器上的 BASH 环境与 IBM Power PC® 处理器上的 BASH 环境是完全相同的。
- 可扩展性 —— shell 提供了将简单的命令拼装成复杂的命令结构的功能。利用脚本和 shell 环境中的数据重定向和管道功能,用户可以构建非常复杂的命令结构来满足自己的需求。而且随着这么多年的发展,很多用户已经利用这些特性开发了非常广泛的工具,他们肯定不想丢弃这些工具。
- 对用户整个工作流程的适用性 —— shell 为应用程序开发、调试、测试和执行提供了一个单一的环境。这是因为 UNIX 工具通常都是使用一个命令行接口开发的,从而让用户可以从 shell 中调用这些工具。不用切换上下文,用户就可以编译、运行并对程序进行调试,这些都可以通过在同一个命令行提示符中调用适当的命令来实现。
由于这些原因,我们决定开发登录 shell,叫做 GridShells,它对传统的 shell 环境的访问能力进行了扩充,已经超出了本地资源,还可以访问分布式/网格资源。具体来说,GridShell:
- 处理所执行的命令类型的限制。
- 不需要对应用程序或底层的分布式/网格基础设施进行修改。
- 为用户对分布式资源提供一种高级的透明性。
而且,GridShell 可以让用户在用户空间安装工具,而不需要任何其他特权或 root 权限。
GridShell 包含了很多扩展,它们可以通过 UNIX shell 来启用网格功能。我将介绍 GridShell 的扩展在 shell 脚本或用户命令行提示符中实现功能强大的网格计算功能的一些简单例子。
GridShell 让用户可以通过在命令行的末尾添加一个 "on <host name>" 结构就能够调度一个命令在分布式远程资源上执行。例如,用户可能希望列出某个远程主机上 /tmp 目录的内容,例如:
%> ls ?l /tmp on host1 |
用户可能还希望在选择主机执行命令时给定一个特定的资源需求。这种资源需求可以使用 "with" 关键字指定。这个关键字的参数是为该命令指定的资源规范,会将其传递给底层的所选主机的资源代理程序。例如,NASTRAN 仿真需要在一个至少具有 25MB 的空闲内存的 SPARC 机器上运行,这个参数如下:
%> nastran with "mem > 25 && type == SPARC " |
如果这个环境中已经实现了适当的资源代理程序,那么 GridShell 就会将这个命令分发到满足指定的资源需求的主机上。在我们的体系架构中,资源字符串会被传递给一个执行插入代理,后者使用一个资源代理服务来获得符合条件的主机列表。将来可以支持资源规范的例子包括 Condor ClassAds 的 match-making 和 LSF 的 lsplace 资源规范。
GridShell 也可以使用 "in <number> instances" 结构提交 作业组。这样可以指定多个实例,一起称为一个组,由 GridShell 扩展插入代理提交到底层的批处理队列系统中。下面这个例子声明,有 cmkin.exe 命令的 20,000 个实例要提交到集群的批处理队列环境中:
%> cmkin.exe in 20000 instances |
然而,生产批处理系统通常都会限制可以提交到自己队列上的作业的数目。如果用户在 _GRID_THROTTLE 环境变量中指定了限制,那么 GridShell 就会限制提交作业组。GridShell 将继续只提交这种限制的作业到批处理队列中,直到所有的作业都已经成功通过作业队列提交分发为止。
GridShell 还可以并行执行命令。用户可以指定使用 "on <number> procs" 结构,这样可以让 GridShell 在此环境中执行一个命令的多个并行实例。同样,GridShell 也要使用一个执行插入代理来远程执行这些命令。这个插入代理可以使用远程执行器,例如 globus-job-run、SSH、lsrun 等等,这取决于到底安装的是哪种插入代理。
GridShell 的关键字也可以进行组合使用。例如,用户可以同时使用 "on" 和 "with" 关键字来说明对选来并行执行程序的主机的要求。下面这个命令将在 3 个计算机节点上执行 /bin/hostname,每个节点都需要至少有 25 MB 内存:
%> /bin/hostname with "mem > 25" on 3 procs |
GridShell 可以通过环境变量对并行执行的每个任务进一步控制它的执行角色。例如,环境变量 _GRID_TASK_NUM 和 _GRID_TASKID 告诉每个任务一共有多少个任务,以及它们在并行执行过程中的角色重要程度如何。这对于单程序多数据(Single Program Multiple Data,SPMD)和主从类型的并行执行模式都非常有用,此时任务的评级可以决定它在并行执行过程中的角色。
GridShell 并行执行的命令也可以本身就是脚本。如果是这种情况,这些脚本需要通过使用重定向操作符 > 和 < 彼此进行通信。这些脚本可以使用 task_<task number> 关键字中任务的个数来确定与哪些任务进行通信。
例如,评级大于 0 的任务在结束计算之后可能要与任务 0 进行通信,如下面的 TCSH 脚本所示:
if ( $_GRID_TASKID > 0 ) then
echo "I am finished" > task_0
endif
|
类似地,任务 0 在最终报告自己执行完成之前,可能会等待脚本中并行执行的所有其他任务已经完成的消息。下面是 TCSH 脚本中的循环:
@ n = 1
while ( $n < $_GRID_TASK_NUM )
ack='cat < task_$n'
@ n = $n + 1
Done
echo "Computation complete!"
|
GridShell 还采用了新的语法让任务将数据广播到并行执行该命令的所有任务中。任务可以通过在重定向到标准输出上时指定 task_all 关键字来实现这种功能:
echo "$initial_data" > task_all |
类似地,任务可能会希望等待并行执行该命令的其他任务输入数据,这可以通过在重定向输入时指定 task_any 关键字来实现:
set response = 'cat < task_any' |
GridShell 还重定义了 < 和 > 操作符,目的是让 shell 可以访问远程文件。目前的实现可以以一个 GSIFTP URL 的形式在对标准输入和标准输出进行重定向来指定远程文件。例如,用户可以使用下面的命令行指定命令的标准输出重定向到远程主机的一个文件上:
%> echo "Hello World" > gsiftp://compute-9-2/tmp/test.txt |
类似地,用户可以指定将远程主机上的一个文件的内容重定向到某个命令的标准输入上:
%> cat < gsiftp://compute-9-2/tmp/test.txt |
在下面这个例子中,我们将详细介绍一个脚本,它的功能是在 GridShell 所派生的两个任务之间来回发送消息。这是 GridShell 并行脚本的一个例子。这个脚本的名字是 ping_pong.gtcsh。
脚本 ping_pong.gtcsh
1: #!/usr/local/bin/gtcsh 2: 3: if ($# < 1) then 4: echo "specify message file" 5: else 6: set send_file=$1 7: endif 8: 9: grid -io on 10: if ( "$_GRID_TASKID" == "0" ) then 11: cat $send_file > task_1 12: cat < task_1 > /dev/null 13: else 14: set ack_file="/tmp/pp_ack.$$" 15: cat < task_0 > $ack_file 16: cat $ack_file > task_0 17: /bin/rm -f $ack_file 18: endif |
第 1 行调用 GridShell 的 TCSH 版本(gtcsh),第 3 到 7 行进行一些基本的命令行处理。
第 9 行是 GridShell 部分真正开始的地方。它告诉 GridShell 脚本使用重定向操作符 > 和 < 开始进行任务间通信。第 10 行确定是否是任务 0。在这个例子中,如果脚本判断是任务 0,那么第 11 到 12 行说明它就会将 $send_file 的内容发送给任务 1(使用关键字 task_1),并等待它返回数据(然后将其重定向到 /dev/null 上)。如果该脚本判断自己是任务 1,就执行 14 到 17 行:从任务 0 中接收数据,并将其重定向到文件 /tmp/pp_ack.$$ 中。
调用 ping_pong.gtcsh 脚本可以使用下面的命令行来实现:
%> ping_ping.gtcsh on 2 procs |
实际上,GridShell 会为这两个主机查询资源代理程序,并在每个选定的主机上派生 ping_pong.gtcsh 脚本,这可以使用 Globus 或由底层批处理队列环境(例如 LSF 和 PBS)提供的远程执行服务。
利用 GridShell,我们希望为计算研究人员提供一个透明的 shell 环境,从而最大限度地利用分布式/网格计算环境中的资源。
我们相信 GridShell 可以通过将分布式/网格计算结构映射为一个大家比较熟悉的环境来提高计算科学家的生产效率。另外,当一位科学家切换到一个不同的集群计算平台上时,他们并不需要重新学习新的提交/执行结构。GridShell 通过提供一个“一次编写,随处运行”的环境,隐藏了很多细节。使用 GridShell,可以构造很多自动化脚本,用于在运行不同资源管理系统(例如 PBS、LSF 或 Condor)的集群上运行。
学习
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文。
-
“网格进展: 开发广域的网格”(developerWorks,2005 年 6 月)简要介绍了德州大学的网格项目。
-
“网格实践:利用空闲的机器周期”(developerWorks,2005 年 6 月)展示了 United Devices 的 Grid MP 如何用来帮助在德州大学的网格项目中利用空闲机器周期。
-
“网格进展:管理资源管理器”(developerWorks,2005 年 7 月)简要介绍了网格的元调度器,这是一种对资源管理器进行管理的方法。
-
GridShell 是一个正在由 Texas Advanced Computing Center 进行研究和开发的工具。它对 TCSH 和 BASH 的语义进行了一些扩展,从而可以透明地将有用的分布式和网格计算的概念集成到 UNIX shell 的登录环境中。
-
The Globus Alliance 是网格计算领域负责开发基础技术的一个社区组织和个人。
-
Condor ClassAds 将属性名映射为表达式。
-
请访问 developerWorks 的 Grid computing 专区,其中提供了非常丰富的信息,可以帮助您理解和利用网格计算技术。
获得产品和技术
-
Load Sharing Facility(LSF)是一个通用的分布式队列系统,由 Platform Computing Corp. 开发,它将很多计算机聚集为一个单一的虚拟系统来更好地利用网络上的资源。
-
Portable Batch System (PBS)是一个非常灵活的批处理队列系统,它有两个版本:PBS Pro 是一个商业版本;OpenPBS 是由 NASA 在 20 世纪 90 年代早期开发的 PBS 的最初版本,它可以在基于网络的多平台的 UNIX 环境中使用。
讨论
-
通过参与 developerWorks blogs 加入 developerWorks 社区。

Edward Walker 是位于奥斯汀的德州大学的一名副研究员。他是 Texas Advanced Computing Center(TACC)的 Distributed and Grid Computing Group 的一名成员。TACC 负责部署和维护高级计算基础设施,旨在通过 National Science Foundation TeraGrid 项目,满足奥斯汀的德州大学以及全国其他组织机构中的教员、职员和学生的计算研究需要。在加入 TACC 之前,他曾经是 Platform Computing Corp. 的一名资深开发人员,负责开发分布式资源管理工具的软件:Load Sharing Facility。他还曾经是新加坡国立大学的一名研究科学家。他的研究兴趣包括普适计算、编译器/计算机语言的设计、并行处理以及计算机体系架构。