服务器的稳定高性能计算能力可以给我们的研究提供新的解法或思路,鉴于网上很少有关于服务器比较全面的入门知识,我在这里做个简单的介绍。

服务器浅谈


简单来说,服务器 ( Server ) 就是一台台日夜不休的电脑,它们通常被放在专用的机房里以提供一个稳定的计算环境。我们可以简单的认为服务器在结构组成上和个人电脑 ( Personal Computer, PC ) 的主机几乎没有区别,该有的结构,像 CPU 、硬盘等它都有,但是由于需要提供可靠的服务,因此在处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面要求较高。当我们需要长时间稳定的高性能计算时,个人电脑可能会因为种种原因崩溃死机重启,这时服务器就是我们最好的选择。

对于初学者而言,服务器和 PC 最大的区别就它们运行的操作系统 ( Operating System, OS ) 。我们知道 PC 上一般运行各种版本的 Windows 系统,Mac 上运行的则是苹果公司自己的 MacOS 系统,而服务器上运行的一般则是各种发型版本的开源 Linux 系统( 国内多使用 CentOS ), 或者运行微软公司推出的服务器专用 Windows Server 系统,后者相对比较少见。在这里我们主要介绍使用 Linux 系统的服务器,本文默认大家都掌握一些最基本的 Linux 系统命令。

远程登录服务器


前面说到服务器就是很多放在机房里的电脑主机,所以当我们需要使用它们的时候,就需要通过远程登录来控制服务器进行计算,一般我们使用 SSH 来远程登录服务器。

安全外壳协议 ( Secure Sell, SSH )

是目前较可靠,专为远程登录和其他网络服务提供安全性的协议,最初是 Unix 系统上的一个程序,后来迅速扩展到其他操作平台。目前几乎所有操作系统,包括所有的类 Unix 系统 ( 各种发行版本的 Linux 以及 MacOS ) , 甚至较新版本的 Windows 系统都已经自带 SSH 。

初次使用 SSH


在 MacOS 或者 Linux 系统中很简单,打开系统自带的终端 Terminal ( MacOS 系统极力推荐 iTerm2 作为 Terminal 的替代品 ),输入命令:

ssh usrname@address

就可以了,其中 usrname 是服务器管理员给你新开的账号用户名,address 是服务器在内网中的地址,比如 10.30.13.121。如果 usrname本机用户名相同的话,可以省略 usrname 直接:

ssh address

对于 Windows 系统,较新版本的 PowerShellCMD 可以直接使用 SSH ,使用方法同上。微软最近开源的 Windows Terminal 项目可能是未来最优的方式,有兴趣的同学可以将 GitHub 上的代码 clone 下来自行编译,或者将 Win10 系统升级到最新的开发者内测版本,然后在 Windows Store 里就可以直接下载 Windows Terminal ( Preview ) 预览版体验一番。当然也可以使用第三方软件,比如 PuTTYXShell终端模拟器都是不错的选择。

在正确输入上条命令后,根据提示输入密码,然后回车,一般就能够成功登录了。

登录后可以看到服务器管理员写的一些使用须知,熟悉 Linux 系统的同学应该立刻就发现了:现在我们就在服务器系统当前登录账户的根目录 ( ~ ) 下了,剩下的一切就和 Linux 系统相同了。

SSH 使用设置


SSH 的设置文件在本机根目录下的 .ssh 目录里 ( . 开头的文件或文件夹默认是隐藏状态,使用 ls -a 命令查看或者直接 cd .ssh 进入目录 ) ,一般使用过一次 SSH 登录后就会自动生成,如果没有该目录可以自己 mkdir .ssh 创建一个,同样在远程服务器当前登录账户的根目录下也会有一个 .ssh 文件夹。

  • 有时我们会发现 SSH 连接莫名其妙的断开了,其实这是因为你一段时间没有任何操作后 SSH 自动断开,我们只需要进入本机根目录下的 .ssh 文件夹,在 config ( 如果没有就自己使用 Vim 或其他文本编辑器新建一个,可能还需要使用 chmod 600 config 命令来给该文件授予权限 ) 文件中添上一句:
    ServerAliveInterval 60
    

    就可以解决这个问题了。

  • 有时本机用户名和我们登录服务器所用的用户名不同,我们可以在 config 文件中写上
    Host hostAlias
      HostName address
      User usrname
    

    hostAlias是你为该节点取的自定义别名,同样 HostName 后的 address 是服务器在内网中的地址 (IPADDR) ,usrname 是你登录服务器所用的用户名。保存后我们直接使用 ssh hostAlias 命令就可以登录服务器了。

SSH 文件传输


至于 SSH 的文件传输使用的则是 scp ( secure copy ) 命令。

  • 例如,要将桌面上的 a.txt 上传到服务器根目录下 b 文件夹中:
    scp ~/Desktop/a.txt usrname@address:~/b/
    

    注:scp 命令和 ssh 使用相同的用户名和密码。

  • 将服务器根目录下 b 文件夹中的 c.txt 下载到本机桌面上:
    scp usrname@address:~/b/c.txt ~/Desktop/
    
  • 如果传输的是文件夹,则在 scp 后加上 -r 表示递归 ( recurse ) 就好了:
    scp -r usrname@address:~/b ~/Desktop/
    

注意: Windows 下路径使用的是反斜杠 \ 分隔

SSH 免密登录


每次 SSH 登录或者 scp 传输文件都要输入密码,感觉很麻烦。我们可以在本机终端输入命令:

ssh-keygen -t rsa

如果看不明白可以暂时无视接下来的一切提示,一直回车到底。 系统会在 .ssh 文件夹下生成一个名为 id_rsa.pub秘钥文件。 将其复制到远程服务器的 ~/.ssh 目录下,并命名为 authorized_keys ( 第一次可能需要使用 chmod g-w authorized_keys 命令来给该文件授予权限 ) 就 OK 了,以后若有别的秘钥,直接添加到 authorized_keys 文件末尾就好了。 此后我们使用本机通过 ssh 登录该服务器时就不用输入密码了,而且使用 scp 传输文件时也不用再输入密码了。

在服务器上执行任务


守护进程


对于单进程串行程序,其编译执行过程同 Linux 系统中一样。在服务器上我们可以通过 nohup ... & 命令来守护进程守护进程的意思就是即便我们退出登录,服务器仍会继续运行程序。比如使用 nohup command > output 2>&1 & 命令,其中 command 为所执行任务的命令,输出结果到 output 文件,2>&1 表示把标准错误 ( 2 ) 重定向到标准输出 ( 1 ) 中,这样一来如果报错的话,错误信息也会被输出到 output 文件中。

我们还可以通过 jobs, ps 或者 ps -ef 命令来查看任务信息( ps -ef | grep usrname 可以查看指定用户正在执行的任务 ),使用 kill PID 命令来杀死进程 ( Process ) ,其中 PID 是前面任务信息命令所提供的进程号

PBS/LJRS 任务管理系统


对于多节点多 CPU 处理器 ( Processors ) 并行计算的程序,服务器一般会使用一个批处理作业和计算机系统资源管理软件来管理各用户提交的任务,最常见的就是 PBS ( Portable Batch System ) 任务管理系统

PBS 是目前功能最为齐全,历史最悠久,支持最广泛的本地集群调度器之一,包括 OpenPBSPBS ProTorque 三个主要分支版本。其中 OpenPBS 是最早的 PBS 系统,目前已经没有太多后续开发,PBS ProPBS 的商业版本 ( 付费 ) ,功能最为丰富。TorqueClustering 公司接过了 OpenPBS ,并给与后续支持的一个开源版本。各种版本的 PBS 系统的操作几乎都是类似的,我们服务器上使用的是联想开发的一个类似 PBS 的任务管理系统 LJRS ( Lenovo Job & Resource Management System ) ,其操作指令和 PBS 几乎完全相同,有的命令只需要把 pbs 改成 ljrs 就可以了,我们后面的介绍都是基于 LJRS 任务管理系统的。

graph TB A(Master node)-->B[Queue 1] A(Master node)-->C[Queue 2] A(Master node)-->D[....] B-->E(Node 1-1) B-->F(Node 1-2) B-->G(....) C-->H(Node 2-2) C-->I(Node 2-2) C-->J(....) D-->K(Node x-2) D-->L(Node x-2) D-->M(....)
服务器集群结构示意图 ( 流程图需代码转换后渲染,可能加载较慢 )

首先介绍一下服务器集群的结构,这里说的不是服务器的物理结构,而是服务器节点之间的关系。参观过机房的同学就会发现机房里有很多台服务器,这每一台服务器我们称之为一个节点 ( node ) 。每个节点的配置不尽相同,可以有多个 CPU 和 GPU 以供使用。数个节点组合在一起构成一个队列 ( queue ) ,所有的队列和节点都归一个管理 ( master ) 节点控制。我们之前 SSH 登录的就是 master 节点,它一般只提供管理任务的功能,计算性能不是很强,所以我们一般不在 master 节点上运行程序。

常用命令

LJRS 提供一个 PBS 系统没有的命令来查看节点情况:

shownodes

如上图所示,该服务器集群有三个队列 dpool1, dpool2 和 dpool3 ,每个队列下有数个节点,如 c0105, c0106 之类,我们可以再次通过 SSH 登录到相应节点下进行运算( 这时 address 就是节点名 ),但是并不推荐这么做。节点后面跟着的数字表示该节点 CPU 处理器使用情况,0/8 表示该节点 8 个 CPU 处理器目前都被使用了,只有 0 个可用,这也可以从颜色提示上直接看出来。

  • 如果想查看节点的详细硬件配置信息,可以使用 ljrsnodes ( PBS 系统则是 pbsnodes ) 命令。

  • 使用 showq 命令可以查看服务器上所有已提交任务的信息,大家可以自己试一试。

  • 使用 qstat 命令可以查看当前用户所提交任务的信息,加上 -q 参数后,即 qstat -q 可查看所有可选队列

提交任务

我们一般使用 pbs 或者 ljrs 脚本来提交任务,也可以通过给 qsub 命令添加参数提交任务,但前者更加方便而且易于阅读和保存,所以这里仅介绍通过脚本提交任务的方法:

给出一个典型的 pbs 脚本的例子,假如我们有一个已经 MPI 并行化后的程序,其可执行文件为 test.exe, 我们新建一个 run.ljrs ( 文件名和后缀名都可任意修改 ) 脚本,写入:

#!/bin/bash

### Job name
#LJRS -N Test

### Queue name
#LJRS -q dpool2

### Number of nodes
#LJRS -l nodes=2:ppn=8

#LJRS -l     cput=1200:00:00
#LJRS -l walltime=1200:00:00

#LJRS -o stdout_file
#LJRS -e stderr_file


WORKDIR=$LJRS_O_WORKDIR
NCPU=`wc -l < $LJRS_NODEFILE`

LAUNCH="mpiexec -machinefile $LJRS_NODEFILE -np $NCPU "
PROGRAMEXEC="./test.exe"

cd ${WORKDIR}
${LAUNCH} ${PROGRAMEXEC} > output

wait

其中所有的 LJRSPBS 系统下则替换为 PBS 。熟悉 Linux 脚本的同学很容易理解这个脚本,第一行声明使用 Bash 解释器解释该脚本。#LJRS -N 后为任务名#LJRS -q 声明调用哪个队列#LJRS -l 声明对该队列的节点调用nodes=2 说明调用 2 个节点 ( 也可以直接写节点名,如 c0112 ) ,每个节点使用 8 个 CPU 处理器 ppn=8,后面一些 #LJRS 设置不明白的话可以暂时不用更改。

脚本的主体部分很简单,就是 cd 到工作目录,然后 mpiexec 执行 MPI 并行程序,将结果输出到 output 文件中,最后的wait 命令会等所有并行进程完成后再结束任务。如果没学过 MPI 编程,则可以在该脚本中改变参数,传入程序后多次执行,实现伪并行,这同样可以调用多节点多处理器进行并行运算。

将脚本保存在工作目录下,使用 qsub run.ljrs 提交任务脚本,然后我们就可以使用前面提到的 qstat 命令或者 showq 命令查看所提交任务的信息。如果不想执行该任务了,使用 qdel JOBID 删除任务,其中 JOBIDqstat 或者 showq 命令显示任务信息中所提供的任务号

结语


到此,我已经对服务器的基本知识做了一个简单的入门级介绍,更多高级的设置和功能需要在日常使用中慢慢学习探索。文中涉及到的 Linux 命令都是最基本的的系统命令,需要我们在日常学习和使用过程中加深对其的理解。最后,希望各位都会有所收获。🎉 🎉 🎉

Go to the Home Page

Sponsor the author if you like the contents!