弄hadoop总是需要折腾不少机器,单单执行 rsync
就挺折腾人的,有时还要排除部分机器来查看一堆机器使用内存情况,等等。以前都使用 expect
结合 for in
来实现,总归简单用着也觉得还行。
但是最近,升级hadoop、tez、安装ganglia被折腾的不行。复制 for
语句到累,原来看过 pdsh
的介绍,不过原来就部署4-5台机器,最近查找Ganglia安装问题的博文里面再次 pdsh
,觉得非常亲切和简洁。再次安装使用也就有了本文。
安装
1
2
3
4
[root@bigdatamgr1 pdsh-2.29]# umask 0022
[root@bigdatamgr1 pdsh-2.29]# ./configure -h
[root@bigdatamgr1 pdsh-2.29]# ./configure --with-dshgroups --with-exec --with-ssh
[root@bigdatamgr1 pdsh-2.29]# make && make install
挺多选项的,用 disgroups
加上 ssh
差不多够用了,以后不够用的时刻再慢慢研究这些选项。
当然更简单的安装方式是使用yum: yum install pdsh -y
简单使用
使用pdsh管理机器的前提是已经建立了到目标机器的SSH无密钥登录,而建立这N台机器的无秘钥登录还是少不了 expect
(当然你愿意一个个输入yes和密码也是OK的)!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看,安装的ssh/exec
[esw@bigdatamgr1 ~]$ pdsh -L
# 设置默认使用的模块
[esw@bigdatamgr1 ~]$ export PDSH_RCMD_TYPE=exec
[esw@bigdatamgr1 ~]$ pdsh -w bigdata[1-2] ssh %h hostname
bigdata2: bigdata2
bigdata1: bigdata1
# 命令行指定模块
[esw@bigdatamgr1 ~]$ pdsh -R ssh -w bigdata1,bigdata2 hostname
bigdata2: bigdata2
bigdata1: bigdata1
# 一个个的指定
[esw@bigdatamgr1 ~]$ pdsh -w ssh:bigdata1,ssh:bigdata2 hostname
bigdata2: bigdata2
bigdata1: bigdata1
[esw@bigdatamgr1 ~]$ pdsh -w ssh:bigdata[1,2] hostname
bigdata2: bigdata2
bigdata1: bigdata1
1
2
3
4
5
6
[esw@bigdatamgr1 ~]$ pdsh -w bigdata[1-2,5,6-8] -X nodes hostname
bigdata5: bigdata5
bigdata6: bigdata6
bigdata2: bigdata2
bigdata8: bigdata8
bigdata7: bigdata7
pdsh除了使用 -w
来指定主机列表,还可以通过文件来指定,如编译时的 --with-machines
,同时可以通过读取默认的位置的文件来获取。在编译pdsh时可以通过 --with-dshgroups
参数来激活此选项,默认可以将一组主机列表写入一个文件中并放到本地主机的 ~/.dsh/group
或 /etc/dsh/group
目录下,这样就可以通过 -g
参数调用了。同时 -X groupname
可以用来排除主机列表中属于groupname组的主机(下面会提到group分组)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[esw@bigdatamgr1 ~]$ export PDSH_RCMD_TYPE=ssh
[esw@bigdatamgr1 ~]$ mkdir -p .dsh/group
[esw@bigdatamgr1 ~]$ cd .dsh/group/
[esw@bigdatamgr1 group]$ vi nodes
bigdata1
bigdata3
[esw@bigdatamgr1 ~]$ pdsh -g nodes hostname
bigdata3: bigdata3
bigdata1: bigdata1
[esw@bigdatamgr1 ~]$ pdsh -w bigdata[1-8] -X nodes hostname
bigdata2: bigdata2
bigdata8: bigdata8
bigdata5: bigdata5
bigdata6: bigdata6
bigdata4: bigdata4
bigdata7: bigdata7
-w
参数也可以用来读取特定文件中的主机列表,同时结合其他规则和进行过滤(具体查看man帮助)。-x
在主机列表基础上进行过滤(提供多一种的方式来实现过滤)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[esw@bigdatamgr1 ~]$ cat slaves | head -2
bigdata1
bigdata2
[esw@bigdatamgr1 ~]$ pdsh -w ^slaves hostname | head -5
bigdata8: bigdata8
bigdata6: bigdata6
bigdata5: bigdata5
bigdata2: bigdata2
bigdata3: bigdata3
[esw@bigdatamgr1 ~]$ pdsh -w ^slaves,-bigdata[2-8]
pdsh> hostname
bigdata1: bigdata1
pdsh>
pdsh> exit
[esw@bigdatamgr1 ~]$ pdsh -w ^slaves,-/bigdata.?/
pdsh@bigdatamgr1: no remote hosts specified
[esw@bigdatamgr1 ~]$ pdsh -w ^slaves -x bigdata[1-7] hostname
bigdata8: bigdata8
当一台主机的输出多余一行时,pdsh输出的内容看起来并不和谐。使用dshbak格式化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[esw@bigdatamgr1 ~]$ pdsh -w bigdata[1-2] free -m | dshbak -c
----------------
bigdata1
----------------
total used free shared buffers cached
Mem: 64405 59207 5198 0 429 31356
-/+ buffers/cache: 27420 36985
Swap: 65535 57 65478
----------------
bigdata2
----------------
total used free shared buffers cached
Mem: 64405 58192 6213 0 505 29847
-/+ buffers/cache: 27838 36566
Swap: 65535 58 65477
批量SSH无密钥登录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[hadoop@hadoop-master4 ~]$ cat ssh-copy-id.expect
#!/usr/bin/expect
## Usage $0 [user@]host password
set host [lrange $argv 0 0];
set password [lrange $argv 1 1] ;
set timeout 30;
spawn ssh-copy-id $host ;
expect {
"(yes/no)?" { send yes\n; exp_continue; }
"password:" { send $password\n; exp_continue; }
}
exec sleep 1;
[hadoop@hadoop-master4 ~]$ pdsh -w ^slaves ./ssh-copy-id.expect %h 'PASSWD'
# 验证是否全部成功
[hadoop@hadoop-master4 ~]# pdsh -w ^slaves -x hadoop-slaver[1-16] -R ssh hostname
参考
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
pdsh -w ssh:user00[1-10] "date"
此命令用于在user001到user0010上执行date命令。
pdsh -w ssh:user0[10-31],/1$/ "uptime"
此命令在选择远程主机时使用了正则表达式,表示在user010到user031中选择以1结尾的主机名,即在user011、user021、user031上执行uptime命令
-l 指定在远程主机上使用的用户名称。例如:
pdsh -R ssh -l opsuser -w user00[1-9] "date"
对于-g组,把对应的主机写入到/etc/dsh/group/或~/.dsh/group/目录下的文件中即可
[root@dispatch1 ~]# pdsh -w dispatch1,search1,horizon1 -l bigendian jps
[root@dispatch1 ~]# vi servers
dispatch1
search1
horizon1
[root@dispatch1 ~]# pdsh -w ^servers -l bigendian hostname
dispatch1: dispatch1
horizon1: horizon1
search1: search1
-f 设置同时连接到远程主机的个数
dshbak格式化输出
pdcp -R ssh -g userhosts /home/opsuser/mysqldb.tar.gz /home/opsuser #复制文件
1
2
3
Some quick tips on how to get started using pdsh:
Set up your environment:
export PDSH_SSH_ARGS_APPEND=”-o ConnectTimeout=5 -o CheckHostIP=no -o StrictHostKeyChecking=no” (Add this to your .bashrc to save time.)
–END