部署+使用集群的算力跑CPU密集型任务

我先在开头做一个总结,表达我最终要做的事情和最终环境是如何的,然后我会一步步说明我是如何搭建。

要做的事情

尝试如何使用多台机器的算力共同跑一个CPU密集型或者GPU密集型的任务。这里以CPU密集型为例子。

在多台机器搭建MPI环境,构建MPI集群共同跑1亿个数据的快排任务,并且对机器的各种指标(如CPU,内存,磁盘,网络等)做可视化监控

最终环境

我这里选择的云平台是Microsoft Azure,使用两台机器做实验,两台操作系统信息一致为:Linux (ubuntu 18.04) Standard B2ms (2 vcpu,8 GiB 内存),两台虚拟机实现了ssh免密互通,通过nfs在其中一台虚拟机创建共享空间,让另一个虚拟机可以远程挂载访问,两台虚拟机通过rpc进行通信,两台虚拟机都配置好了可以运行MPI的环境,配置好了prometheus+node_exporter+grafana,每个服务所需要的端口都已经通过azure安全组打开。

如何配置?

1.虚拟机初始化

我选用了Microsoft Azure的产品,订阅了UoL-Teaching-SOC-MCC后,找到了给我分配的资源组:* uol_feps_soc_comp5850m_xxxxxx。(学校给我分配的,大家可能要自己去购买使用)我在上面构建了两台虚拟机,一台叫做jhvm(51.11.167.xx),另一台叫做jhvm2(20.254.126.xx),同时在两台虚拟机上我都创建了同样的用户名mppi,为了保证登录的安全性,我选择使用密钥进行登录,即:

ssh -i jhvm_key.pem mppi@51.11.167.xx

即公钥会保存在服务器上,私钥则在本地,在创建虚拟机的时候,Azure会问你是否使用非对称密钥进行登录,选择是后,即可下载.pem文件。

2.如何实现两个虚拟机的免密登录

首先为了不再使用ip而是使用昵称,我在/etc/hosts上增加了:

51.11.167.xx node1
20.254.126.xx node2

/etc/ssh/sshd_config中设置

PubkeyAuthentication yes

确保开启了密钥登录。对node1和node2节点的家目录设置权限为700,否则可能会存在免密登录失败的问题,在node1上,我通过

ssh-keygen -t rsa

生成公钥私钥到.ssh目录,把**.ssh目录权限设置为600**,主要不能有写权限,不然可能会免密失败,然后通过

ssh-copy-id -i .ssh/id_rsa.pub mppi@node1
ssh-copy-id -i .ssh/id_rsa.pub mppi@node2

命令后,输入了node2用户mppi的密码,把公钥放到了node2的.ssh/authorized_keys文件中,同时再使用scp命令把私钥也复制给node2节点(node1也要,因为他会放进authorized_keys文件中,让node2也能免密登录node1)。

scp .ssh/id_rsa node2:/home/mppi/.ssh

至此,node1和node2都同时有了公钥和私钥,我们输入ssh node2命令,即可免密登录进node2,node2使用ssh node1也能免密登录进node1。

3.mpi集群环境搭建

切换到root权限,我们执行

apt-get install mpich

命令即可下载mpi环境。把qsort.c放到/home/mppi/mpi_share里。**这里不会对mpi原理过多讲解,主要还是如何使用工具搭建好要的环境。**感兴趣的话大家可以google或者baidu等自行搜索。这里的代码主要作用是获取Input.txt文件的内容:先获取文件的第一个数字n,代表有n个数,然后获取n个数,即我随机生成的n个数,然后会把排序好的数据放到output.txt中,input.txt和output.txt名字可以通过参数指定。mpi可以通过-n指定cpu个数。

对mpiexec(mpirun)感兴趣的同学,可以通过man mpiexec(mpirun)去查看说明文档。

/*qsort.c - Parallel sorting algorithm based on quicksortOriginal code by Hans-Wolfgang LoidlHeriot-Watt University, EdinburghAdapted by Karim DjemameExecution time includes input, processing and outputFebruary 2023compile: mpicc -Wall -o qsort qsort.crun:     mpirun -np num_procs qsort in_file out_filenum_procs: number of processorsin_file: input file to sortout_file: result fileExample: on a single machine:mpirun -np 2 qsort input.txt output.txt
*/#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>double startTime;/* swap entries in array v at positions i and j; used by quicksort */static inline /* this improves performance; Exercise: by how much? */
void swap(int *v, int i, int j) {int t = v[i];v[i] = v[j];v[j] = t;
}/* (quick) sort slice of array v; slice starts at s and is of length n */
void quicksort(int *v, int s, int n) {int x, p, i;// base case?if (n <= 1)return;// pick pivot and swap with first elementx = v[s + n / 2];swap(v, s, s + n / 2);// partition slice starting at s+1p = s;for (i = s + 1; i < s + n; i++)if (v[i] < x) {p++;swap(v, i, p);}// swap pivot into placeswap(v, s, p);// recurse into partitionquicksort(v, s, p - s);quicksort(v, p + 1, s + n - p - 1);
}/* merge two sorted arrays v1, v2 of lengths n1, n2, respectively */
int *merge(int *v1, int n1, int *v2, int n2) {int *result = (int *)malloc((n1 + n2) * sizeof(int));int i = 0;int j = 0;int k;for (k = 0; k < n1 + n2; k++) {if (i >= n1) {result[k] = v2[j];j++;} else if (j >= n2) {result[k] = v1[i];i++;} else if (v1[i] < v2[j]) { // indices in bounds as i < n1 && j < n2result[k] = v1[i];i++;} else { // v2[j] <= v1[i]result[k] = v2[j];j++;}}return result;
}int main(int argc, char **argv) {int n;int *data = NULL;int c, s;int *chunk;int o;int *other;int step;int p, id;MPI_Status status;double elapsed_time;FILE *file = NULL;int i;if (argc != 3) {fprintf(stderr, "Usage: mpirun -np <num_procs> %s <in_file> <out_file>\n", argv[0]);exit(1);}MPI_Init(&argc, &argv);MPI_Comm_size(MPI_COMM_WORLD, &p);MPI_Comm_rank(MPI_COMM_WORLD, &id);char processorname[100];int namelen;MPI_Get_processor_name(processorname, &namelen);printf("processor %i of %i running on machine %s\n", id, p, processorname);MPI_Barrier(MPI_COMM_WORLD);elapsed_time = - MPI_Wtime();if (id == 0) {// read size of datafile = fopen(argv[1], "r");fscanf(file, "%d", &n);// compute chunk sizec = (n % p != 0) ? n / p + 1 : n / p;// read data from filedata = (int *)malloc(p * c * sizeof(int));for (i = 0; i < n; i++)fscanf(file, "%d", &(data[i]));fclose(file);// pad data with 0 -- doesn't matterfor (i = n; i < p * c; i++)data[i] = 0;}// start the timer
//  MPI_Barrier(MPI_COMM_WORLD);
//  elapsed_time = - MPI_Wtime();// broadcast sizeMPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);// compute chunk sizec = (n % p != 0) ? n / p + 1 : n / p;// scatter datachunk = (int *)malloc(c * sizeof(int));MPI_Scatter(data, c, MPI_INT, chunk, c, MPI_INT, 0, MPI_COMM_WORLD);free(data);data = NULL;// compute size of own chunk and sort its = (n >= c * (id + 1)) ? c : n - c * id;quicksort(chunk, 0, s);// up to log_2 p merge stepsfor (step = 1; step < p; step = 2 * step) {if (id % (2 * step) != 0) {// id is no multiple of 2*step: send chunk to id-step and exit loopMPI_Send(chunk, s, MPI_INT, id - step, 0, MPI_COMM_WORLD);break;}// id is multiple of 2*step: merge in chunk from id+step (if it exists)if (id + step < p) {// compute size of chunk to be receivedo = (n >= c * (id + 2 * step)) ? c * step : n - c * (id + step);// receive other chunkother = (int *)malloc(o * sizeof(int));MPI_Recv(other, o, MPI_INT, id + step, 0, MPI_COMM_WORLD, &status);// merge and free memorydata = merge(chunk, s, other, o);free(chunk);free(other);chunk = data;s = s + o;}}// stop the timer
// elapsed_time += MPI_Wtime();// write sorted data to out file and print out timerif (id == 0) {file = fopen(argv[2], "w");fprintf(file, "%d\n", s);   // assert (s == n)for (i = 0; i < s; i++)fprintf(file, "%d\n", chunk[i]);fclose(file);// stop the timerelapsed_time += MPI_Wtime();printf("Quicksort %d ints on %d procs: %f secs\n", n, p, elapsed_time);}MPI_Finalize();return 0;
}

同时在同一个目录下添加mpi_config文件,输入(即node1和node2都开启两个cpu去跑的意思)

node1:2
node2:2

然后为了测试我们mpi集群是否搭建成功,我们按照qsort.c文件的入参要求,设置了input.txt和output.txt,其中input.txt里我放了1 million个数字做测试,第一个代表要排序数字的个数n,后面跟着n个数。然后为了测试是否是成功运行在两台机器上,把qsort.c通过命令编译成qsort:

mpicc qsort.c -o qsort

通过mpiexec -n 4 -f mpi_config ./qsort 1_million.txt 1_output.txt命令执行后,通过输出发现jhvm和jhvm2都分别有2个进程在做运算,说明我的环境搭建成功。

在这里插入图片描述

失败的同学可能是mpi需要的端口没开。

4.nfs和rpcbind搭建

NFS(Network File System)主要功能是通过网络来做文件存储,使用NFS可以实现多台服务器之间数据共享,NFS之间通过rpc进行通信。这里同样不会对原理过多讲解,主要还是如何使用工具搭建好要的环境。感兴趣的话大家可以google或者baidu等自行搜索。

通过

apt-get install nfs-kernel-server
apt-get install rpcbind
# 失败的同学可以先执行apt-get update, 刷新源索引列表

命令下载好nfs共享目录的工具和rpc通信方式(启动的时候需要先启动rpc,因为nfs需要先找到rpc去绑定),我选择使用node1节点作为主节点,修改/etc/exports文件,添加配置:

/home/mppi/mpi_share node1(rw,sync,no_root_squash,no_subtree_check)
/home/mppi/mpi_share node2(rw,sync,no_root_squash,no_subtree_check)
# 可参考 https://blog.csdn.net/weixin_45361475/article/details/117754118
# 可参考 http://events.jianshu.io/p/3035c7636d23

里面的地址就是要共享目录的位置,然后我们分别在node1和node2的这个位置去创建文件夹mpi_share,然后启动node1节点的rpc服务再启动nfs-server服务,node2也需要启动rpc并通过

mount -t nfs node1:/home/mppi/mpi_share

命令挂载到node1同位置目录上。然后我尝试在node1节点创建了一个文件,在node2同位置路径下也出现了相同文件,说明我搭建成功了,我们以后有任何要计算的任务,可以只把文件复制到node1节点上即可,不需要手动的去复制到node2,或者集群扩充后的node3等等,非常的方便。

不使用nfs+rpc其实mpi也能跑,但是需要自己手动复制文件到node2节点,用mpi跑的时候直接**-hosts**即可:

mpirun -n 4 -hosts node1:2,node2:2 ./qsort input.txt output.txt

5.node_exporter

通过教程了解并且搭建好node_exporter, prometheus, Grafana,这三者的关系是:prometheus是可以通过node_exporter获取到多个机器的各种指标信息,Grafana是对prometheus的可视化。

搭建教程:https://medium.com/devops-dudes/install-prometheus-on-ubuntu-18-04-a51602c6256b

通过教程在整合过程中,我发现教程给的node_exporter版本号太低了,所以我后面自己重新下载了0.18.1版本的node_exporter(因为在grafana很多现成的dashboard都需要node_exporter版本0.18或以上),随后跟着教程把node_exporter二进制文件放到/usr/local/bin里管理,同时为node_exporter构建一个不可登录的用户去管理,然后在创建/etc/systemd/system/node_exporter.service,配置好unit,service和install后,重新加载守护进程,运行node_exporter即可。

6.prometheus

也是通过给的教程,安装了2.1.0版本的prometheus,同样也是把二进制文件放到/usr/local/bin里,为prometheus创建一些数据目录:/etc/prometheus /var/lib/prometheus,把一些配置文件,像consoles或者console_libraries等放到/etc/prometheus里。

添加prometheus的配置文件:/etc/prometheus/prometheus.yml,设置抓取速率等,配置job_name和指标可用的端口号,为prometheus也创建一个不可登录的账号进行管理,并修改权限,以免被修改。随后也创建prometheus.service配置好unit,service和install,重新加载systemd,然后运行prometheus即可。通过ip:9090成功显示网页,环境成功搭建。

7.Grafana

这里和node_exporter一样,我没有使用教程给的版本号,而是使用的9.2.3版本,因为5.0.4实在太老了,很多dashboard不能用。解压后root下通过systemctl daemon-reload && systemctl 启用 grafana-server && systemctl start grafana-server.service即可。通过url:ip:3000有dashboard界面,我成功搭建了grafana。在grafana指定了data sources后,输入了对应的ip:9090,并且我在 https://grafana.com/grafana/dashboards/?dataSource=prometheus 找到了一个非常合适的、同时也是非常流行的dashboard:node exporter full,可以可视化主机上很多的性能指标,比如cpu、内存、磁盘、网络等等。配置好后即可显示vm上的各项指标。

实验设计

我会分为两个部分,第一个部分则是最为简单的单个虚拟机情况,第二个则是双虚拟机集群情况。

我会分别尝试单机开启2,4,8个进程去跑100万、500万、1000万和2000万的快排数据,也就是说会有3x4=12个输出。比如说2个进程的时候跑100万、500万、1000万和2000万的随机生成数据。

生成数据的原则:当要生成100万数据的时候,我随机生成的范围为0-200万,跑500万、1000万和2000万数据的时候,随机的范围则和他们的数据量大小相等。

单机部分我会根据本虚拟机cpu个数,和开启的进程个数,快排算法跑完时间做对比才考,并且会通过grafana可视化cpu、磁盘、内存的情况,做出分析和总结。

在第二个集群跑快排的部分,我同样会有12个输出,3种不同的进程数量尝试4种不同数量大小的快排。同样会去根据两边cpu的总个数,一共开启的进程数,通过grafana去查看cpu、内存、磁盘去思考+总结

实验结果

单台

在一台具有2cpu的虚拟机上,我们尝试在不同数量的进程下运行100万、500万、1000万和2000万个随机数的数据大小。我们发现,只有当CPU数量=进程数量时,快速排序的效率最高,并且已经验证了计算密集型工作与CPU之间的关系是平等的,效率更高。我们还注意到,只有在运行数千万数据时,内存才会略有波动。如果不使用mpi等高效的流程协作工具,也不使用快速排序等高效算法,那么内存使用和CPU使用将更加明显。一个是因为CPU需要很长时间,另一个是由于数千万的数据本身已经是数百兆字节。

在这里插入图片描述

node1 grafana:

在这里插入图片描述

跑2000万数据,单台虚拟机的cpu飙升到60%多。

多台

事实上,得出的结论与单个虚拟机的结论相似。接下来,我将重点介绍与单个虚拟机报告的不同之处。因为我们使用一个集群(两台机器)来运行快速排序算法,所以使用了这两台机器的所有CPU,从而增强了计算能力,而且我们还可以发现,当使用2cpu/每台vm时,集群状态所需的计算时间更少,这也意味着我们的集群可以充分利用每个vm的资源来分配操作,对于一些需要复杂操作并且可以划分为子操作的任务来说,这无疑是个好消息。

在这里插入图片描述

node1 grafana:

在这里插入图片描述

node2 grafana:

在这里插入图片描述


愿每个人都能带着怀疑的态度去阅读文章并探究其中原理。

道阻且长,往事作序,来日为章。

期待我们下一次相遇!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/60255.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

今年你们赚到钱了吗?

峥嵘的2022年&#xff0c;各位程序员们&#xff0c;你们赚到钱了吗&#xff1f; 今天是2022年12月21日&#xff0c;眼看就快过年了&#xff01; 今年你们赚到钱了吗&#xff1f;对于我而言&#xff0c;又是一个"窘迫/囧迫"的穷年&#xff0c;有点心慌慌&#xff0c;有…

教你一招利用python在网上接单赚钱,月薪过万太香了

前言 学习python编程&#xff0c;不仅可以找到一份高薪工作&#xff0c;而且不打算转化或者是在校学生的话&#xff0c;也能为你的日常生活提高一些帮助&#xff0c;比如&#xff1a;自动化办公 爬取一些数据信息之类的…另外闲暇时间也可以在网上接点小单&#xff0c;增加些收…

业余时间赚“外块”的话。给你汇总了用Python挣钱的4个方式,一起来瞧瞧吧~

渠道一&#xff1a;程序流程代笔 到淘宝网/猪八戒在网上搜&#xff1a;Python程序流程。随后到对应的店里找在线客服&#xff0c;便说你要做程序流程开发&#xff0c;是不是可以给个联系电话。渐渐地聊熟识了&#xff0c;还可以变成她们店面里的做兼职技术工程师。 或是添加一…

2023年靠Python接私单赚钱可太香了

假期&#xff0c;闲来无事回顾过去的一年&#xff0c;收益最大的还得是Python爬虫接私单&#xff0c;每每和大家分享都甘之如饴&#xff0c;单看一两个单子可能没什么感觉&#xff0c;但一单接一单&#xff0c;一个月的收获非常可观&#xff01; 这是近期做的爬虫单子&#xf…

宝剑锋从磨砺出 梅花香自苦寒来(高考志愿篇)

各省高考成绩已出&#xff0c;又到一年高考季。张雪峰提到&#xff1a;“普通家庭不要光谈理想&#xff0c;也要谈落地。”志愿怎样填报、选专业还是选学校、什么专业好就业、高考志愿主要看什么&#xff1f;针对这些疑问&#xff0c;你对正在选志愿的毕业生们有什么建议吗&…

海淀育新学校2021高考成绩查询,首师附育新“加工能力”不容小觑!海淀7000名以内可“签约”实验班...

近两年海淀北片的几所高中学校 也越来越受到家长的关注 今天给大家整理了一些 首都师范大学附属育新的数据 例如2021中招计划、班级设置及高考成绩 供今年即将中考的家长参考 下面一起来看看吧 01 2021年招生计划 首都师范大学附属育新学校位于西三旗街道新康园4号。学校2021年…

DDD案例说明

1、案例说明 整个专栏的案例来源于一个虚构的公司&#xff0c;公司里有一个虚构的团队&#xff0c;他们真实的业务章程&#xff0c;并且有一个真实的软件系统需要部署开发部署&#xff0c;而他们所面临的DDD挑战和问题也是真实存在的。 这个公司叫做SaaSOvation。正如名字所示…

Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day15】—— Spring框架1

大家好&#xff0c;我是陈哈哈&#xff0c;北漂五年。认识我的朋友们知道&#xff0c;我是非科班出身&#xff0c;半路出家&#xff0c;大学也很差&#xff01;这种背景来北漂&#xff0c;你都不知道你会经历什么&#x1f643;&#x1f643;。   不敢苟同&#xff0c;相信大家…

update多表联合更新

t_student表和t_class表 Mysql UPDATE db_shop.t_student s,db_shop.t_class c SET s.class_namec.name,c.stu_names.name WHERE s.class_idc.id --等效于 UPDATE db_shop.t_student s JOIN db_shop.t_class c SET s.class_namec.name,c.stu_names.name WHERE s.class_…

oracle update 多表关联更新

oracle 多表 关联 更新 先看例子 select t.*, t.rowid from T1 t;select t.*, t.rowid from T2 t;错误示范&#xff1a; update t1 set t1.money (select t2.money from t2 where t2.name t1.name);结果&#xff1a; 因更新条件不够&#xff0c;可以看到name不相等的mone…

linux普通账户变为管理员,你就可以将普通账户升级为管理员账户了

当每台电脑装上系统后&#xff0c;都会有一个Administrator管理员账户&#xff0c;它是Windows默认的最高权限用户&#xff0c;它有权力对系统进行任何等级设置或删除应用&#xff0c;而一般的帐户就只有对这个系统的使用权&#xff0c;没有管理权。那么&#xff0c;我们可以将…

Power Automate Forms 提交表单 到 Teams 群组中的Excel行

新建一个Forms表单 Teams 研究群组 中新建一个 个人信息.xlsx 注意&#xff1a;一定要是xlsx格式 个人信息.xlsx 中 设置表格 在Power Automate 中 找一个 Forms 开始的模板 删除原来SharePoint 的部分 添加Excel Online 选择 在表中插入新行 建立 Forms 和Excel 表格的 对应…

社区电商平台除了小红书,这个运营社群的平台你肯定没用过!

有的阿&#xff0c;比如有赞、粉丝圈、云之家等等......&#xff0c;现在的微信生态圈在不断的完善&#xff0c;不仅仅是社交内容层面上的不断优化&#xff0c;社群平台更多的是打开了服务自己店铺的用户端口&#xff0c;不断在这个空间内扩大自己的用户池。 就来说说粉丝圈吧…

小红书店铺的所有商品API接口(整店商品详情查询接口)

小红书店铺的所有商品API接口&#xff08;整店商品详情查询接口&#xff09;代码对接如下&#xff1a; 1.公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff0c;点击获取请求key和secret &#xff09;secretString是调用密钥api_nam…

如何打造爆款单品?小红书品牌营销全链路解决方案来了

导语 爆款单品已经成为小红书品牌增长的捷径。爆款单品能让新锐品牌实现从0到1的增长&#xff0c;那么能让网红品牌从1到10吗&#xff1f; 《小红书品牌营销全链路解决方案》专栏第二部分&#xff1a;网红单品打造。与大家一起探讨如何打造爆款单品以及延长它的生命周期。 01…

2021年小红书电商直播趋势报告-小红书数据分析报告

千瓜数据独家推出《2021年小红书电商直播趋势报告》&#xff0c;基于2020年春节期间小红书直播数据&#xff0c;通过直播大盘数据概览、品牌自运营探究、直播观众画像、直播达人洞察等方面&#xff0c;分析小红书直播数据&#xff0c;前瞻2021年小红书电商直播趋势和解决方案。…

直播电商,小红书的商业化“解药”?

配图来自Canva可画 随着互联网流量增长日趋放缓、广告业务逐渐疲软&#xff0c;商业化焦虑就成为了当下整个互联网行业需要共同面对的难题。在此背景下&#xff0c;目前最火热的赛道——互联网直播带货就成为了不少平台和公司寻找新增量的重要方向&#xff0c;以及寻求商业化破…

小红书电商入驻全流程指南

小红书电商入驻全流程指南#小红书 五类店铺入驻要求可售卖类目你知道吗&#xff1f;#运营#干货 你知道小红书的 5 类店铺的入驻要求以及可售卖类目吗&#xff1f;hello&#xff0c;大家好&#xff0c;我是专注搞流量的百收编辑狂潮老师。小红书目前支持的五大类型的店铺分别是…

小红书自研小程序:电商体验与效果优化的运行时体系设计

小程序在其诞生后的几年内&#xff0c;凭借其简单、轻量、流畅、无需安装等特点&#xff0c;引来了爆发式的增长。伴随小红书电商业务的发展&#xff0c;我们洞察到越来越多的商家和品牌大客户有自己定制化需求场景&#xff0c;传统的电商和薯店存在下面三大问题&#xff1a; 为…

facebook怎么运营?

很多做跨境的小伙伴都是通过facebook进行聊天交友&#xff0c;通过facebook平台去做营销引流获客。大家在做facebook营销的时候难免会遇到一些问题&#xff0c;尤其是账号封禁申诉、facebook运营等等一系列内容&#xff0c;下面跨境王营销助手就为大家详细讲解下&#xff0c;希…