欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多机MPI

程序员文章站 2022-03-06 13:56:03
...

因为所作研究工作计算量真是太大了,一台z840的48核工作站还是感觉有点慢,所以就想着自己搭建一个小的集群环境,正好办公室里面有台人家不用z800,所以就拿过来试了一下。

折腾了两天,终于在两台hp z840和z800装有centos7的工作站上搭建好了MPI并行环境。还是有很多地方需要注意的,稍有不慎,就会发生错误。下面对这两天的工作进行一下总结,就算抛砖引玉吧。。。

首先呢,两台装有linux的工作站得相互之间能够进行通信,我采用直连的方式,因为工作站一般有两个网口(两张网卡),所以我就用z840的一个网口接内网,一个网口接外网,两张网卡使用nat服务(其实就是对防火墙进行配置)进行桥接,这样两台计算机就都能上外网了,把买交换机或者路由器的钱省下了,而且相对安全,处在内网上的计算机是在z840建的局域网中,外面是访问不到的。至于nat服务这里就简单放两个命令吧:

设置局域网IP、网段、子网掩码、网关这些不用多说了吧,计算机进入中国好多年了,不会设置的有点对不起国家这些年对计算机的大力发展呀,回去趴被卧好好哭一场吧。

命令如下
 

  1. iptables -t nat -A POSTROUTING -j MASQUERADE -o enp5s0 (这个是目标网卡,即连接外网的网卡)
  2. iptables -F
  3. iptables -X

这样另外一台计算机就可以上外网了。

另外需要多说一点的是,由于centos默认情况下只有一个显卡是开机自启的,而我这显示器也最多只能接两台,(北京地价大家都知道的,能省一分是一分), 我就把两台显示器都接到了z840上面,不是我偏心,毕竟z800是台slave,用不用显示器都无所谓的。这样就造成一个问题,就是如果我重新启动z800,系统启动起来了,但是网卡没启动起来,这样远程连接又控制不了,又得折腾找显示器整,太麻烦,所以得设置网卡开机自启,具体修改方法如下

修改/etc/sysconfig/network-scripts/ifcfg-enpxxxxxx(xxx)文件,其内容原本如下

  1. TYPE=Ethernet
  2. BOOTPROTO=dhcp
  3. DEFROUTE=yes
  4. PEERDNS=yes
  5. PEERROUTES=yes
  6. IPV4_FAILURE_FATAL=no
  7. IPV6INIT=yes
  8. IPV6_AUTOCONF=yes
  9. IPV6_DEFROUTE=yes
  10. IPV6_PEERDNS=yes
  11. IPV6_PEERROUTES=yes
  12. IPV6_FAILURE_FATAL=no
  13. NAME=enp0s31f6
  14. UUID=f0feed49-a691-4081-b8cb-22226eab82d3
  15. DEVICE=enp0s31f6
  16. ONBOOT=no //把no改成yes就开机自启了

另外如果需要配置静态地址,也可以通过修改该文件

如果想要自己设置静态ip,需要在上边文件的最后添加以下内容:

 

  1. IPADDR=192.168.7.106 #静态IP
  2. GATEWAY=192.168.7.1 #默认网关
  3. NETMASK=255.255.255.0 #子网掩码
  4. DNS1=192.168.7.1 #DNS 配置

使用 service network restart 命令重启网卡服务即可联网。

两台机器相互通信正常了,下面就得相互间可以免密访问,因为MPI是基于ssh服务,而我们平时的远程连接是需要输入账户,密码的,你想呀,在进行MPI通信的时候,一台计算机计算得到的数据要传输到主机上,总不能每次都得输入帐号、密码吧,所以得账户之间做个免密处理,具体方法如下:

首先用来搭建环境的两台主机的主机名不能一样(注意:是主机名,不是用户名),默认情况下,不进行设置,一般主机名是localhost域名为localdomain,可以通过查看/etc/hostname或者/etc/hosts文件进行查看,应为MPI是通过主机名进行连接的而不是用户名。如果主机名仍然都是localhost的注意了,需要进行更改,更改方法如下:

1、手动更改 /etc/hosts文件,把旧的主机名删除,保存文件就行了,但是不仅仅只有这一个文件需要修改,还有一些,不知道的可以去网上查一查;

2、利用hostnamectl命令进行主机名称的修改,具体命令如下

 hostnamectl set-hostname <newhostname>

当然是在超级用户权限下,这条命令会删除/etc/hostname文件中的主机名,然后替换为新的主机名。和第一种方法一样,我们也需要更新/etc/hosts文件,这两种方法的本质是一样的。

3、hostname进行临时修改,具体命令如下

hostname <new-hostname>

这条命令不会更改/etc/hostname文件中的静态主机名(static hostname),它更改的只是临时主机名(transient hostname)。所以重启计算机后会回到旧的主机名。

各台机器的主机名配置好了以后,下面就开始配置各个节点的登陆权限了

(1)host配置(所有节点)

超级用户权限下打开/etc/hosts文件

在hosts文件中添加所有节点的IP地址和相应的主机名称,比如我这是两台机器进行互联,配置如下
 

  1. 192.168.10.250 master(主机IP 主机名)
  2. 192.168.10.252 slave(主机IP 主机名)

然后保存,在没台机器上均进行同样的设置,最后可以用ping命令测试是否连通

(2)集群机器的ssh登陆权限配置

对每一个节点(我这里是两台计算机),分别生成公钥和私钥,命令如下

  1. cd ~/.ssh/ # 若没有该目录,请先执行一次ssh localhost
  2. ssh-****** -t rsa # 会有提示,接着连按3次回车
  3. cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys #将自己的公钥追加到authorized_keys里

对每一台机器均作上述处理,然后将生成的id_rsa.pub都传到一个节点的.ssh目录中,然后用cat命令全部追加到authorized_keys文件中,然后将该文件分别传送到每一台机器的相应目录下。如果还不明白,参照https://my.oschina.net/zctzl/blog/1560593

然后对ssh免密登陆进行测试,在命令行中输入指令

  1. ssh slave
  2. ssh master

如果没有密码登陆,则表示ssh免密登陆成功。但是大多数情况下没有这么顺利,如果出现了密码登陆界面,请检验追加的公钥是否正确,若还是不行请确保ssh服务开启。同时查看相应文件是不是配置正确,这里列出相对应的参数

打开/etc/ssh/sshd_config

作如下修改

        RSAAuthentication yes # 启用 RSA 认证

        PubkeyAuthentication yes # 启用公钥私钥配对认证方式

        AuthorizedKeysFile .ssh/authorized_keys # 公钥文件路径(和上面生成的文件同)

然后重新启动ssh服务

/bin/systemctl restart sshd.service

另外还有一个很重要的问题,是我总结出来的,如果想直接通过ssh 主机名的方式进行免密登陆,需要每个节点的用户名是一样的,因为通常情况下,用ssh登陆其他用户一般都是ssh 用户名@主机名的形式,如果直接用ssh 主机名这种方式,默认情况下用户名是当前用户名,所以如果是这样是登陆不上去的,巧合的是,可以通过修改./ssh文件夹下的config文件来对主机用户进行标定,格式如下(以我的机器为例),

将master主机下的config文件改为

Host slave (主机名)

user slave (用户名) 就是说用master来连接slave的话,用户名是slave(我的slave主机用户名就是slave)

将slave主机下的config文件改为

Host master

user master (与上面同理)

就是能够让主机互联就是了,不懂的可以摸索一下。

(3)mpich的安装

安装就不用多说了把,mpich已经相当成熟,不存在一些软件安装时候需要各种库,各种依赖,安装包里面也有说明文件,README,这里就不再多说了。但是尤其需要注意的一点是,所有机器的mpich需要安装到同一个目录下比如装在/usr/local下就全部装在这个路径下,因为运行并行程序的时候,发送的可执行文件的地址就是相同的,如果你装在/home/username下,由于每台机器的用户名不一样,这样发送任务会失败。(尤其注意这一点)经常出现/hydra_pmi_proxy:no such file or directory等

(4)程序测试

按照上面的要求安装完成以后,原则上是可以运行并行程序了,但是有一点,MPI要求再每台机器下面都要有相对应的可执行文件以及参数文件等,就是说每次运行程序前都要把参数文件、可执行文件放在相同的目录下,这样的话就太麻烦了,尤其是参数文件比较大的时候。因此这里需要一种只对文件复制一次,然后其他计算机再用的时候过来读就行了,这种可以通过NFS文件系统进行实现。具体实现过程如下

(5)创建NFS文件系统

如果不进行这一步mpi程序也可以正常运行,但是需要保证在每个节点上的相同路径下都有可执行文件,所以每次都要把可执行文件进行远程拷贝,非常麻烦!也可以参照https://blog.****.net/coolwubo/article/details/60779933。

服务端:master(192.168.10.250)

客户端:slave(192.168.10.252)

1、服务端安装配置

        安装nfs-utils和rpcbind,centos直接yum install即可

创建共享目录

mkdir dir  这里需要说明的是dir具有其他用话的读写权限

        配置/etc/exports

多机MPI

  1. #参数说明
  2. #rw:read-write,可读写;
  3. #ro:read-only,只读;
  4. #sync:同步写入(文件同时写入硬盘和内存),适用在通信比较频繁且实时性比较高的场合
  5. #async:异步写入(文件先写入内存,稍候再写入硬盘),性能较好(速度快),适合超大或者超多文件的写入,但有数据丢失的风险,比如突然断电等情况;
  6. #注意:除非特別有需要,否则不建议使用 async。如果沒有指定 sync 或 async,NFS 服务器在启动的时候会印出警告信息。
  7. #no_root_squash:NFS客户端连接服务端时如果使用的是 root 的话,那么对服务端分享的目录也使用 root 权限。不安全!
  8. #root_squash:把客户端 root 身份的 UID/GID (0/0) 对应到服务端的 nobody 用户去,即服务端使用 nobody 用户来操作共享目录;
  9. #all_squash:不论NFS客户端连接服务端时使用什么用户,对服务端分享的目录来说都是拥有匿名用户权限;
  10. #anonuid:匿名用户的UID值,通常是nobody或nfsnobody,可以在此处自行设定;
  11. #anongid:匿名用户的GID值。

 

        启动服务,并设置开机启动

  1. sudo service rpcbind start
  2. sudo service nfs start
  3. sudo chkconfig --level 2345 rpcbind on
  4. sudo chkconfig --level 2345 nfs on

 

        2.客户端配置

sudo yum -y install nfs-utils rpcbind

        创建目录

sudo mkdir dir   //dir的要求同上

        查看服务端共享目录

showmount -e 192.168.10.250

        挂载共享目录到本地,并测试读写:

 

  1. sudo mount -t nfs 192.168.10.250:/dir /dir
  2. #最开始,我将共享目录放在/home/mpiuser下的dir文件夹内,虽然dir的权限为777
  3. #但是由于其父目录(即用户目录mpiuser)的权限为700,所以挂载时遇到服务器拒绝访问的问题
  4. #于是我将共享目录放在根目录下,并将其权限设置为777,否则需要增加用户目录的访问权限
  5. cd /dir && touch test

        设置开机自动挂载:

 

sudo vim /etc/fstab
10.10.1.1:/mpiShareDir     /mpiShareDir                    nfs     defaults        0 0

        上述步骤完成后,以后只需将mpi程序放在mpiShareDir目录下就可以直接运行,而不需要使用远程拷贝。

简单的运行程序验证一下,基本上是可以的了。

注意要点

1、多台机器的防火墙设置

这个至关重要,如果这个出问题,前面作的再对,也找不到原因,很难检查;

具体见前面nat服务,出现的错误常有

引自https://blog.****.net/yhsweetlife/article/details/46654181

[email protected]:~/nfs_he$ mpirun -f nodes -n 3 ./example1
rank :0 ,source: -1 ,dest: 1
rank :2 ,source: 1 ,dest: 0
Fatal error in MPI_Send: Unknown error class, error stack:
MPI_Send(174)..............: MPI_Send(buf=0x7ffd4cc4db30, count=5, MPI_INT, dest=1, tag=5, MPI_COMM_WORLD) failed
MPID_nem_tcp_connpoll(1832): Communication error with rank 1: Connection refused


===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   PID 18691 RUNNING AT yuanhe
=   EXIT CODE: 1
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
[proxy:0:[email protected]] HYD_pmcd_pmip_control_cmd_cb (pm/pmiserv/pmip_cb.c:885): assert (!closed) failed
[proxy:0:[email protected]] HYDT_dmxu_poll_wait_for_event (tools/demux/demux_poll.c:76): callback returned error status
[proxy:0:[email protected]] main (pm/pmiserv/pmip.c:206): demux engine error waiting for event
[[email protected]] HYDT_bscu_wait_for_completion (tools/bootstrap/utils/bscu_wait.c:76): one of the processes terminated badly; aborting
[[email protected]] HYDT_bsci_wait_for_completion (tools/bootstrap/src/bsci_wait.c:23): launcher returned error waiting for completion
[[email protected]] HYD_pmci_wait_for_completion (pm/pmiserv/pmiserv_pmci.c:218): launcher returned error waiting for completion
[[email protected]] main (ui/mpich/mpiexec.c:344): process manager error waiting for completion
 

2、免密登陆的用户名设置

一般我们再设置用户名的时候不会设置成相同的的,这个时候就需要仔细设置一下./ssh/config文件,否则没有办法直接通过ssh 主机名进行免密登陆

3.NFS文件系统的权限设置,所有机器都必须对这区域有读写权限,经常出现的错误如下

引自http://www.heminjie.com/system/linux/2998.html

NFS是非常通用和简单的Linux下共享协议,但是最近安装了一次,在另一台CentOS用mount挂载时却出现“access denied by server while mounting”这个错误;
 
因为之前配置过很多次NFS了,都没出现过一点问题,于是先试试在本机mount挂载,测试可以挂载,但是在另一台机器上却报错,首先想到的是iptables防火墙问题,于是关闭防火墙,也一样报错。
 
去网上搜索了一下,遇到这个错误的人也很多,但是原因都不大相同,在这里我就总结一下出现此错误的几种原因:
 
1、使用了非法端口,也就是使用了大于1024的端口。
这个错误,可以通过查看日志确认:
[[email protected]~ /]# cat /var/log/messages | grep mount
Jan 2 12:49:04 localhost mountd[1644]: refused mount request from 192.168.0.100 for /home/nfsshare/ (/home/nfsshare): illegal port 1689
 
解决办法:
修改配置文件/etc/exports,加入 insecure 选项,重启nfs服务,再尝试挂载。
/home/nfsshare/  *(insecure,rw,async,no_root_squash)
 
2、NFS版本问题
编辑/etc/sysconfig/nfs文件,找到下面:

#Turn off v2 and v3 protocol support 
#RPCNFSDARGS="-N 2 -N 3" 
#Turn off v4 protocol support 
#RPCNFSDARGS="-N 4"  /*把这句前面的#号去掉*/

最后保存,重启nfs服务,再尝试挂载;如果挂载不上,可尝试在后面加-o nolock参数。
 
3、查看客户端挂载的目录是否具备读写权限,添加相应权限即可。
 
4、nfs服务器上的/etc/hosts中设置了客户端机器IP对应域名,去掉即可。
 
通过以上这几种方法,access denied by server while mounting这个错误应该可以得到解决了。

/////就介绍这么多了,这是我再实际操作中遇到的问题,希望能帮到大家!!!

 

相关标签: 并行计算