级别: 初级 Dana French, 总裁, Mt Xia Inc.
2009 年 6 月 15 日 作业假脱机或假脱机处理是大型机概念,可以在 IBM® AIX® 环境中使用,但是很少被人使用。本文讨论在 AIX 环境中实现作业假脱机的配置、原因和用途。
简介
IBM AIX 作业假脱机程序是所有 AIX 系统上非常有用的内置实用程序,但是用户很少启用或使用它。在本文中,“作业” 这个词表示可以在 AIX 系统上执行的任何应用程序、实用程序、程序或 shell 脚本,但是它们不需要来自用户或管理员的交互式响应。AIX 作业假脱机程序让管理员和用户能够提交多个作业,然后每次处理一个作业。按照这些作业提交给假脱机程序的次序处理它们。作业假脱机程序在很多方面都是有用的系统管理工具。例如,作业假脱机的一些用途包括:
-
减少系统管理员的工作量
-
需要逐一执行的进程
-
自动地编辑数据文件
-
访问动态文件中的数据
-
用连接的设备进行输入或输出
-
限制并发进程的数量
-
控制系统负载
-
作业控制
-
作业调度和跟踪
-
在常规业务时间段为在线处理保留资源
-
在工作负载低的时间段执行批处理
在现代数据中心环境中,作业假脱机程序的用途更广泛。在管理大型环境时,许多重要的活动都涉及数据中心自动化,这需要调度进程并可靠地获得处理结果。例如,自动化系统部署需要在构建期间从虚拟化系统动态地分配存储设备、网络地址和虚拟 I/O。因为多个来源都可能发出自动化部署请求,所以必须通过某种机制确保分配给系统的物理和虚拟资源是唯一的。作业假脱机就可以提供这种解决方案。多个来源可以生成系统部署请求,作业假脱机程序接收它们(排队)。然后,作业假脱机程序每次处理一个排队的请求。作业假脱机程序逐一处理请求,这可以避免在同时处理请求时可能出现的重复分配物理或虚拟资源的问题。
AIX 作业假脱机程序配置
AIX 作业假脱机程序集成在队列守护进程中,队列守护进程也控制打印机。在默认情况下,作业假脱机程序队列 bsh 是禁用的。启用 bsh 队列很简单,只需编辑队列配置文件 /etc/qconfig。首先,查看 /etc/qconfig 文件,找到标签为 “bsh:” 的队列定义节以及相关联的队列设备 “bshdev:”。在默认配置中,这些节的每一行前面有一个星号 “*”,表示它们被注释掉了。
# view /etc/qconfig
...
...
...
*
* BATCH queue for running shell scripts
*
*bsh:
* device = bshdev
* discipline = fcfs
*bshdev:
* backend = /usr/bin/bsh
|
作为 root 用户或属于 printq 组的用户,编辑 /etc/qconfig 文件,删除 “bsh:” 和 “bshdev:” 节的每一行前面的星号:
# vi /etc/qconfig
...
...
...
*
* BATCH queue for running shell scripts
*
bsh:
device = bshdev
discipline = fcfs
bshdev:
backend = /usr/bin/bsh
|
修改队列守护进程配置文件 /etc/qconfig 之后,使用 System Resource Controller 命令停止并重新启动队列守护进程:
# lssrc -a | grep qdaemon
# stopsrc -s qdaemon
# startsrc -s qdaemon
# lssrc -a | grep qdaemon
|
停止并重新启动队列守护进程之后,使用 lpstat 命令检查队列状态:
# lpstat -W
Queue Device Status
---- ---- ----
bsh bshdev READY
|
AIX 作业假脱机程序实现
下面给出一个使用 AIX 作业假脱机程序执行批作业的简单示例。这个示例使用 “at” 调度程序在特定的日期和时间向假脱机程序提交作业。在这个示例中,日期和时间是 “now”,但是可以根据需要改为任何日期和时间。示例的第一部分创建一个 shell 脚本,它把一些信息输出到 /tmp 目录中的一个文件。这个脚本还睡眠 0 到 99 秒的随机时间;这是为了产生一些延迟,让用户能够查看队列的内容。通过执行以下命令创建这个示例 shell 脚本:
print -- '#!/usr/bin/ksh93
typeset -R2 T
T=${RANDOM}
print -- "${T} ${0}" > "${0}.out"
date >> "${0}.out"
sleep ${T}
date >> "${0}.out"
' > /tmp/tmp1.ksh
|
创建 /tmp/tmp1.ksh shell 脚本之后,修改此文件的权限,让它成为可执行的。
同时向作业假脱机程序队列和 at 作业调度程序提交作业需要一个复合命令。把 shell 脚本提交给作业假脱机程序的示例命令是 lp -d bsh /tmp/tmp1.ksh。为了调度假脱机程序命令,要使用 Korn shell print 命令把它发送给 at 命令的标准输入:
print -- "lp -d bsh /tmp/tmp1.ksh" | at now
|
如果指定日期/时间为 “now”,那么 at 调度程序立即执行命令。使用 lpstat -t 命令查看作业假脱机程序队列的内容:
# lpstat -t
Queue Dev Status Job Name From To
Submitted Rnk Pri Blks Cp PP %
------- ----- --------- --------- --- --- ----- --- ---- --
bsh bshde RUNNING 86 /tmp/tmp1.ksh dfrench dfrench
03/21/09 20:03:43 1 15 1 1 0 0
/tmp/tmp1.ksh
|
当作业完成时,将创建 /tmp/tmp1.ksh.out 文件,其内容像下面这样:
# cat /tmp/tmp1.ksh.out
50 /tmp/tmp1.ksh
Sat Mar 21 20:03:43 CDT 2009
Sat Mar 21 20:04:33 CDT 2009
|
输出的第一行包含随机选择的睡眠秒数,然后是脚本的名称。下面两行包含执行睡眠命令之前和之后的日期/时间戳。时间戳的差应该是从第一行开始的秒数。
通过使用上面的作业假脱机概念,系统管理员就不再需要判断每个夜间批作业对系统施加的负载。一般情况下,系统管理员通过 cron 调度作业处理,尝试让工作负载比较均衡地分布。管理员要根据每个作业预期的执行时间,确定调度作业处理的时间间隔。通常还会把下一个作业的调度时间延后一段时间,以防前一个作业的执行时间超出预期。
通过使用 AIX 作业假脱机程序,可以同时提交所有不连续的夜间批作业,因为假脱机程序会按照提交次序每次运行一个作业。所以,即使把 50 个作业都安排在 23:00 运行,由于采用了假脱机机制,它们会连续地逐一运行。这样管理员就不需要分散调度作业以避免系统过载。他们可以把作业安排在任何时候运行,只要把作业发送给作业假脱机程序,就会逐一执行每个作业。管理员不再需要判断系统负载并根据可用的系统资源决定调度时间。
cron 调度
当然,前面使用 at 调度程序的技术也可以改为使用 cron 调度程序。只需在 crontab 记录中在要执行的命令前面加上假脱机程序命令。下面的 crontab 记录行在每天晚上 23:00 运行一个命令:
0 23 * * * /usr/bin/lp -d bsh /usr/local/scripts/schedjob.ksh
|
同样,在调度不连续的批作业时,可以把它们都安排在 23:00,因为它们会通过假脱机程序每次运行一个。管理员不需要评估系统负载或作业处理时间。
备份处理
备份处理作业应该安排在所有夜间处理作业完成之后运行,所以它们是假脱机队列中最后一个作业。例如,如果把最后一个夜间处理作业安排在 23:45 提交给作业假脱机程序,那么应该在此时间之后提交备份处理作业:
0 0 * * * /usr/bin/lp -d bsh /usr/local/scripts/backupjob.ksh
|
即使夜间处理作业到 05:00 AM 还未完成,因为备份作业是队列中最后一个作业,所以在夜间处理完成之前它不会开始运行。
连续处理
需要连续处理的作业可以通过 cron 提交给作业假脱机程序,每个作业间隔一分钟。作业在假脱机程序中排队,一个作业完成之后,下一个作业就会开始。管理员不再需要估计作业之间的时间间隔,或者通过创建临时文件触发对下一个作业的处理。作业假脱机确保连续处理每个作业,不会受到处理时间变化的影响。下面的 crontab 记录示例表示一些需要特定处理次序的作业:
0 23 * * * /usr/bin/lp -d bsh /usr/local/scripts/schedjob01.ksh
1 23 * * * /usr/bin/lp -d bsh /usr/local/scripts/schedjob02.ksh
2 23 * * * /usr/bin/lp -d bsh /usr/local/scripts/schedjob03.ksh
3 23 * * * /usr/bin/lp -d bsh /usr/local/scripts/schedjob04.ksh
|
多个作业假脱机
如果有可用的系统资源,可以创建多个作业假脱机,这样就可以通过假脱机程序同时处理多个作业。
# mkquedev -q bsh -d bshdev2 -a 'backend = /usr/bin/ksh93'
|
注意,mkquedev 命令中指定了 Korn Shell 93 /usr/bin/ksh93 命令 shell;可以使用任何有效的 shell 作为后端处理程序。可以根据需要在作业队列中添加任意数量的队列设备,从而高效地利用系统资源,同时维持可控的假脱机环境。在添加另一个队列设备之后,使用 lpstat -W 命令显示与 bsh 作业队列相关联的多个队列设备。bsh 作业队列现在可以在每个可用的设备上处理一个假脱机的作业:如果有两个可用设备,就可以同时处理两个作业,每个设备一个作业。
# lpstat -W
Queue Device Status
---- ---- ----
bsh bshdev READY
bsh bshdev2 READY
|
如果使用多个作业假脱机,而且对备份作业进行假脱机,那么就无法确保在备份作业开始之前完成所有其他作业。
运行以下命令创建一个 shell 脚本,以它为例演示跨多个作业队列设备的作业假脱机:
print -- '#!/usr/bin/ksh93
typeset -R2 T
T=${RANDOM}
print -- "${T} ${0}" > "${0}.out"
date >> "${0}.out"
sleep ${T}
date >> "${0}.out"
' > /tmp/tmp1.ksh
chmod 755 /tmp/tmp1.ksh
|
为了演示跨多个队列的作业假脱机(假设已经创建了第二个作业假脱机队列设备),运行下面的 “for” 循环,向 “bsh” 作业队列提交 10 个作业。
for i in 0 1 2 3 4 5 6 7 8 9
do
lp -d bsh /tmp/tmp1.ksh
done
|
现在,使用下面的 “while” 循环查看前面提交的作业的作业队列状态。在 lpstat -W 命令的每次执行之间睡眠 5 秒:
while true
do
lpstat -W
print -- “# Hit Control-C to end this loop”
sleep 5
done
|
查看完 lpstat -W 命令的输出之后,按 Control-C 中断 “while” 循环。“while” 循环的输出像下面这样。注意,有多个作业处于 RUNNING 状态;每当一个作业完成时,一个 QUEUED 作业就转移到作业假脱机设备队列中并执行。
Queue Dev Status Job Name From To
Submitted Rnk Pri Blks Cp PP %
------- ----- --------- --------- --- --- ----- --- ---- --
bsh bshde RUNNING 76 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 1 15 1 1 0 0
/tmp/tmp1.ksh
bsh bshde RUNNING 77 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 2 15 1 1 0 0
/tmp/tmp1.ksh
QUEUED 78 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 3 15 1 1
/tmp/tmp1.ksh
QUEUED 79 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 4 15 1 1
/tmp/tmp1.ksh
QUEUED 80 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 5 15 1 1
/tmp/tmp1.ksh
QUEUED 81 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 6 15 1 1
/tmp/tmp1.ksh
QUEUED 82 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 7 15 1 1
/tmp/tmp1.ksh
QUEUED 83 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 8 15 1 1
/tmp/tmp1.ksh
QUEUED 84 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 9 15 1 1
/tmp/tmp1.ksh
QUEUED 85 /tmp/tmp1.ksh dfrench dfrench
03/21/09 18:16:14 10 15 1 1
/tmp/tmp1.ksh
|
在有多个作业队列的系统上,对连续作业处理进行假脱机要求把所有作业转发到同一个作业队列设备。在其他情况下,作业被发送到第一个可用的作业队列设备。通过使用前面的 for 循环示例,可以看到排队的作业的执行可以被限制在单一作业队列设备上 (bshdev2):
for i in 0 1 2 3 4 5 6 7 8 9
do
lp -d bsh:bshdev2 /tmp/tmp1.ksh
done
while true
do
lpstat -W
print -- “# Hit Control-C to end this loop”
sleep 5
done
|
把排队的作业的执行限制在作业队列设备 bshdev2 上,就可以确保连续执行这些作业。如果不指定 bshdev2,每个作业会在第一个可用的队列设备上执行,这会导致同时(不连续)运行多个作业。
如果希望删除第二个作业假脱机程序队列设备,从而每次只执行一个作业,那么运行以下命令:
列出队列设备,确认它是要删除的设备:
# lsquedev -q bsh -d bshdev2
bshdev2:
backend = /usr/bin/ksh93
|
删除队列设备:
# rmquedev -q bsh -d bshdev2
|
再次尝试列出这个队列设备。因为前一个命令已经删除了它,现在应该返回一个错误:
# lsquedev -q bsh -d bshdev2
lsquedev: (FATAL ERROR): 0781-190 Queue:device, bsh:/bshdev2: not found in
qconfig file. Not printed.
|
列出默认的队列设备,确认它仍然存在:
# lsquedev -q bsh -d bshdev
bshdev:
backend = /usr/bin/ksh93
|
结束语
内置的作业假脱机程序为 AIX 环境中的许多问题和需求提供了解决方案。本文只讨论了 AIX 作业假脱机程序的几个用途,肯定还有许多其他用途,包括:
-
减少系统管理员的管理工作量。
-
通过消除与负载过高或过低的系统相关联的负载高峰和低谷,优化系统资源的利用率。
-
通过消除处理时间变化造成的错误,提高 cron 调度的作业处理的可靠性。
-
通过程序从数据库或平面文件获得企业范围的惟一标识符,比如 IP 地址。
-
通过程序测试值(比如主机名)是否是企业范围惟一的。
-
通过程序保留物理或虚拟资源,比如虚拟 I/O 适配器。
-
消除同时访问多个数据源所导致的数据文件更新问题。
注意,如果启用 AIX 作业假脱机程序,那么系统上的任何用户都能够向作业假脱机程序提交进程。这些进程以提交作业的用户的身份执行,具有与此用户相同的权限和设置。因此,root 用户提交的作业具有 root 级权限。
在构建要提交给作业假脱机程序的 shell 脚本时,在脚本中定义 PATH 环境变量常常是一种好做法。这确保可以通过此变量中列出的目录访问脚本调用的所有程序、实用程序、函数、脚本等等。
通过创建多个作业队列设备,可以增加同时处理的作业数量,由此增加系统负载和吞吐量。但是,如果配置和启用多个作业队列设备,那么必须把需要连续执行的进程限制在单一作业队列设备上。
可以使用一般的队列管理命令 “disable” 和 “enable” 实现作业控制。可以使用这些命令停止和启动作业队列设备,从而停止和启动作业处理。
参考资料 学习
讨论
关于作者  | 
|  | French 先生在 IT 行业中的从业经验已有三十多年,所涉及的行业也非常之多。他的工作重点主要是业务连续性、灾难恢复以及高可用性等领域,并且他设计和编写了许多软件包,以实现灾难恢复和高可用性过程的自动化。他最大的贡献是将系统管理作为一项自动化的、面向业务的过程(而不是面向系统的、交互的过程)。他还是 Korn Shell 编程领域的著名专家。 |
对本文的评价
|