利用shell脚本在集群环境下自动化跑实验

死线 发布于

缘由

这段时间要给论文跑实验,实验的大致需求如下:

  • 有3个控制变量,即8个组合
  • 要测4~5个版本
  • 每组实验的横坐标为集群中节点的个数

你想想上面的场景如果手动去跑,我算了一下,大概要跑150次以上的实验,就算中途不出错,每次实验平均以15分钟计算,要跑2天。而且你人为的去启动每次实验,晚上还得睡觉,怎么也要个4~5天,关键是非常容易出错,每次需要手动的去改配置文件,不断地的切换工作路径,来回搞个几百次,让我想起了卓别林的《摩登时代》的螺丝工。这时候shell脚本就显得非常有用了,本来脚本设计的初衷就是为了减少人力,可惜我之前没怎么写过,光脚本就写了一天半,而且非常丑陋,不过总算能用 :)

使用数组

首先必须要让脚本辨识不同的机器的地址,最好的办法就是把所有机器的IP存到一个数组,然后想用哪个,直接游标去访问就行:

1
2
3
4
5
6
7
8
9
10
#! /bin/bash
#定义机器IP地址的数组
ip_array=("192.168.0.8" "192.168.0.10" "192.168.0.12" \
"192.168.0.13" "192.168.0.19" "192.168.0.20" \
"192.168.0.22" "192.168.0.24" "192.168.0.18" \
"192.168.0.26" "192.168.0.25" "192.168.0.23" \
"192.168.0.27" "192.168.0.39" "192.168.0.36" \
"192.168.0.34" "192.168.0.38" "192.168.0.35" \
"192.168.0.37" "192.168.0.40" "192.168.0.41" \
"192.168.0.42" "192.168.0.45" "192.168.0.57")

巧用变量

你需要使用一些变量来让脚本理解你想要使用的「控制变量」,这个变量你可以使用「预定义」范围的数,或者是直接从脚本命令行参数传过来,比如下面这种:

1
2
3
4
5
6
7
8
9
10
# 一些变量,可以是你后期去改,也可以是从命令行传过来,或者是常量,但是以后需要手动修改
version=$1
temp=$2
length=$3
nodes=$4
dis=$5
isclock=$6
user="root"
port=22
password=""

如果是从「命令行参数」传过去的,你可以在上层在简历一个父脚本,简单地执行一条条子脚本即可,只需不断的改变参数就行

善用判断语句

如果你访问的集群的机子有着不同的「密码」,亦或者不同的版本需要给配置文件给予不同的参数,你必须要根据当前的变量值给予不同的判断,执行不同的「动作」,shell脚本的判断语法非常坑爹,多个或者少个空格有时候会带来灾难性的后果,例子如下:

1
2
3
4
5
6
7
8
# 根据不同的集群号给予不同的访问密码
if [ $i -le 12 ]; then
password="password1"
elif [ $i == 23 ]; then
password="password2"
else
password="password3"
fi

改变配置文件

这时候你可以使用「sed -i」命令去修改,加入我的配置文件格式是形如「parameter: value」,你可以使用如下的脚本:

1
sed -i 's/parameter:\s[1-9]*[0-9][0-9]*/parameter: your_modify_value/g'

慎用sshpass

这是个开源的可以使ssh指定密码去访问其余节点,然而非常坑爹的是这货有个巨坑的「bug」,在连续执行若干条sshpass -p命令之后,会随机的失败一次,而且不返回任何错误!!!所以还是老老实实的事先将所有机子「贯通」,不使用密码登录即可。

感悟

要学会「偷懒」,而且要趁早,越早越好。我之前一直懒得写脚本,浪费了大量的时间,最后没办法才写了,「收益」也小了很多。

及时地「偷懒」即是勤奋!
–沃兹基朔德

好久没更新文章,最近忙,前面的「ACG」系列会抽空补。