大多数人在服务器上运行命令的时候,爱使用循环或者逐条运行,这其实无法发挥服务器的性能,在不用花的时间上浪费了很多时间,本期我们来从简入难,汇总一下服务器并行的思路

01
—
基础并行,不借助工具
当你有几条很简单的命令,比如
#命令
cmd1
cmd2
cmd3
他们之间彼此独立,互不干涉,这种情况大多数人都知道,只需要后面挂一个&
就可以把命令挂到后台,
#命令
cmd1 &
cmd2 &
cmd3 &
因为彼此独立,所以全挂后台没有影响
但是如果存在依赖,怎么办呢?
比如这种情况,5个命令,但是cmd4和5依赖cmd1和2的输出,其中cmd3是独立的
cmd1
cmd2
cmd3
cmd4
cmd5
这里我们可以借助wait,把cmd1和2先并行运行,然后再运行345
cmd1 &
cmd2 &
wait
cmd3 &
cmd4 &
cmd5 &
到这里其实大多数任务的并行就都没问题了,再往后就是任务很多的情况,需要控制并行数量
02
—
高级并行,借助工具
这里有两个代表性工具,rush和parallel,但是他们的设计层级是完全不同的
简单的说,rush或类似软件叫做并行执行器,parallel则是并行调度器
rush的目的是快速并行,所以使用起来很方便,适合一堆简单任务
parallel则是进行复杂的任务调度的,但是功能更强大
现在假设我有100个txt后缀文件,1-100.txt,现在需要用一个名字叫data_process的程序批量处理他们,我的服务器资源最多并行8个我该如何执行这些命令?
先来介绍rush
# rush 非常简单, {}就是变量
ls *.txt | rush -j 8 'data_process -i {} -o {.}.out'
现用起来非常简单,直接通过-j控制同时并行的数量,用法和for done循环也很类似,改起来很容易,变量改成{}就行,然后是parallel,对于简单命令,他其实也很方便
# parallel 一般推荐使用joblog参数,如果中断可以恢复
parallel -j 8 --joblog job.log data_process -i {} -o {.}.out ::: *.txt
# 中断后 通过resume参数恢复
parallel --resume --joblog job.log data_process -i {} -o {.}.out ::: *.txt
大部分简单任务其实不太会中断,所以这两是等价的,但是如果是复杂任务,还是parallel更好一点
03
—
投放到其他节点(qsub或者类似系统)
一般来说服务器可能存在多个节点,投放系统都是有编写好的软件来调度的,但是如果系统里没有,直接投放也可以,比如我们这个命令可以这样投放
qsub -cwd -V -t 1-$(ls *.txt | wc -l) \
-N myprog \
-b y \
'f=$(ls *.txt | sed -n "${SGE_TASK_ID}p"); data_process -i "$f" -o "${f%.txt}.out"'
这个几乎是最简单的命令了,但是依然比之前的麻烦多了,所以如果每个命令对cpu和内存的资源占用不大,就不需要投放到其他节点,而且如果这个程序对磁盘的读写很高,哪怕使用大量计算资源,整体的速度也快不到哪里去
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!