Ray部署与测试文档
本文档为OSH-2023 My-Glow小组的Lab4文档。
Ray 部署文档环境配置
Ubuntu版本:22.04.2
python版本:3.10.10
pip版本:23.0.1
单机版Ray部署安装RayRay的安装基于pip。运行以下命令安装Ray:
12sudo apt updatesudo pip3 install -U "ray[default]"
自动安装了ray2.3.1版本。
根据官方文档,运行sudo pip3 install -U ray也可;与安装ray[default]的区别在于ray[default]会多安装一些依赖。
Ray cluster部署Ray集群的部署要求集群内的机器在同一局域网下,并且python和Ray版本相同。
在主节点上:运行如下命令:
1ray start --head --port=6379
得到如下输出,则Ray启动成功:
在子结点上:运行如下命令:(该命令即为主节点上运行时输出的命令)
1ray start --address='198.18.0.1:6379'
得到如下输出,则Ray子结点已连接到主节点上:
要结束ray,只需在主节点上运行ray stop即可。
Ray监控在主节点上登陆localhost:8265即可看到所有节点的监控信息。
这里使用了旧ui。
docker部署Ray首先docker的安装见官方文档,换源见中科大docker镜像
Dockerfile如下:
12345678910111213141516FROM ubuntuWORKDIR /COPY . /RUN sudo sed -i 's/cn.archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.listRUN sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.listRUN sudo sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.listRUN sudo apt updateRUN sudo apt install -y python3 && sudo apt install -y python3-pipRUN pip3 config ser global.index-url https://pypi.tuna.tsinghua.edu.cn/simpleRUN pip3 install -U "ray[default]"
使用该镜像来创建ray镜像。步骤如下:
在目录下创建Dockerfile,并将测试的python文件复制到同一文件夹下,如下图:
构建docker镜像:
1docker build -t ray_cluster .
-t参数的目的是将打包的镜像文件命名。
运行docker镜像:
头结点:
1docker run -idt --name ray_head ray_cluster
子结点:(此处子结点开启了两个,可按需求开启)
12docker run -idt --name ray_node1 ray_clusterdocker run -idt --name ray_node2 ray_cluster
-d参数的目的是后台执行容器;-it使得容器不会自动退出,并能够通过终端访问。
进入容器,并开启/连接Ray服务
对于头结点:
123docker exec -it ray_head bin/bash# 以下为容器内部操作ray start --head --port=6379
可以得到与单机版部署类似的输出。
对于子结点:
1234docker exec -it ray_node1 bin/bash# 以下为容器内部操作# address为头结点输出的地址ray start --address='172.17.0.2:6379'
在头结点内运行测试文件即可开始测试。
Ray性能测试与优化测试任务我们组选用的测试任务是计算一定范围内(暴力计算)质数的个数。
选用该任务的原因是该任务计算量大,能够体现出分布式计算的优点;同时暴力计算便于并行化,程序编写简单,且运行时间适中,避免偶然因素影响实验结果。
暴力计算素数个数的核心代码如下:
12345678910111213141516def is_prime(n: int): result = True for k in range(2, int(n ** 0.5) + 1): if n % k == 0: result = False break return resultdef count_primes(n: int) -> int: count = 0 for k in range(2, n): if is_prime(k): count += 1 return countcount_primes(10000000)
Ray性能指标性能指标如下:
CPU占用率:指计算任务在CPU上的负载。
CPU占用率代表了任务在不同节点内对CPU的压力。
总执行时间:指同一程序从开始执行到执行完毕的时间。
总执行时间代表了一项任务分配在不同节点后的性能表现。
平均响应时间:指系统对请求做出响应的平均时间
平均响应时间代表了一个系统对大量请求的处理能力;在Ray系统内可指代从程序开始执行到Ray开始真正计算的间隔。
吞吐量:指系统在单位时间内处理请求的数量。
吞吐量代表了一个系统单位时间内能够处理请求的数量。
响应时间方差:指将所有节点的响应时间排成数列,该数列的方差。
响应时间方差从另一方面代表了一个系统对大量请求的处理能力;如果方差过大,则代表该系统分配任务存在不均衡的情况,该系统的性能大概率会比较低。
在本实验中,我们将监测CPU占用率和总执行时间两个指标;原因是这两个指标易于测量:CPU占用率可以从Ray控制台上直接得到;总执行时间可以在程序中计时得到。
程序计时测量执行时间可能存在系统误差,但拉长执行时间后该系统误差会被稀释,对整体的影响较小,因此可以使用。
不使用Ray进行测试CPU使用率测试结果如下:(使用top监测)
总执行时间时间测试结果如下:
上述结果汇总为表格如下:
运行平台
CPU占用率
执行时间
不使用Ray
98%+(单核)
62.56s
该结果将作为使用Ray测试时的性能基准。
Ray单机性能测试核心代码12345678910111213141516171819202122232425262728293031323334@Ray.remoteclass Compute: def __init__(self) -> None: self.count = 0 def is_prime(self, n: int) -> bool: result = True for k in range(2, int(n ** 0.5) + 1): if n % k == 0: result = False break return result def count_primes(self, start: int, end: int, step: int) -> int: self.count = 0 for k in range(start, end, step): if Compute.is_prime(k): self.count += 1 return self.count def result(self): return self.count def main(): Ray.init() init_time = time.time() computer = Compute.remote() futures = [] future = computer.count_primes.remote(2, 10000000, 1) futures.append(future) result = Ray.get(futures) print(result) print("total time: ", time.time()-init_time)
在一台虚拟机上运行一个头结点和两个子结点,作为Ray集群。
测试运行计算质数个数的代码,得到如下结果:
运行过程中Ray的控制台如下所示:
观测top内CPU的使用率如下:
top内显示Ray计算只用了一个进程,显然没有对多核计算进行优化。
总结出单机运行Ray的性能指标如下表所示:
运行平台
CPU占用率
执行时间
不使用Ray
98%+(单核)
62.56s
使用Ray
<20%(所有核)~100%(单核)
64.32s
可以看到,程序部署在Ray后,运行时间相比未部署的时间反而长了2s(应为Ray分配任务的开销),且CPU的利用率仅不到20%,说明上述代码并没有利用到Ray分布式集群强大的运算能力,应该进行优化。
Ray单机优化性能测试针对上述代码无法利用到Ray性能的问题,考虑将测试代码进行优化。
最初的测试代码只是将任务整体交给Ray,因此用不到Ray的并行计算。因此,在计算任务中,将所有任务手动拆分为小块,并分配给Ray,性能预期将会提升。
修改main函数如下所示:
1234567891011121314def main(): Ray.init() init_time = time.time() # step: 指分组数,每一组内检查的数差值为step step = 10 futures = [] for i in range(step): computer = Compute.remote() future = computer.count_primes.remote(i, 10000000, step) futures.append(future) results = Ray.get(futures) # 因为计算时把0和1也算入质数,因此在这里减去 print(sum(results) - 2) print("total time: ", time.time()-init_time)
代码将待测试的所有数分为10组,并调用多个remote()方法生成多个计算实例并同时计算,从而达到更高的计算性能。
测试结果如下所示:
运行过程中Ray的控制台如下所示:
图中显示第二个节点CPU使用率显著低于其他两个节点,可能原因是其正处于被分配过程中,因此可视为误差。
观测top内CPU的使用率如下:
可见Ray自动开启了多个compute进程,提高了运算速度。
由上述所有总结出单机运行Ray的性能指标如下表所示:
运行平台
CPU占用率
执行时间
不使用Ray
98%+(单进程)
62.56s
使用Ray
<20%(对任一节点)~100%(单进程)
64.32s
使用Ray(代码已优化)
99%+(对任一节点) ~100%(多进程)
20.82s
优化过后代码的性能提升约为3倍,说明利用到并行的代码得到了质的性能提升。
Ray分布式性能测试分布式测试在两台虚拟机上进行。在一台虚拟机上运行Ray的头节点,在另一台虚拟机上运行子结点,从而构成Ray集群。
Ray的控制台如下所示:
两节点的IP地址不同可以证明Ray集群是在两台机器上搭建的。
在头结点运行测试程序,得到如下结果:
观察到两台虚拟机的CPU使用率如下,即CPU负荷均达到最大:
Ray的控制台输出如下所示:
由上述测试结果可以得到Ray已经在多机上完成了分布式部署。
Docker部署性能测试Docker的部署过程见部署文档。在完成部署文档的内容后,机器中应该已经有Docker的镜像了。
在终端1上运行docker镜像,并在内部的终端中运行ray start --head --port=6379,得到如下输出:
类似的,在终端2的docker内运行ray start --address='172.17.0.2:6379',有以下输出:
由于docker内无法通过浏览器显示ray控制台,因此在头结点内使用ray status查看集群的状态:
可见在docker搭建的ray集群内有两个节点,即两台终端分别对应的节点。
在头结点内运行测试文件,得到如下输出:
这个结果与单机上部署多个ray节点测试结果类似,说明在docker上部署是成功的。
随便看看
- 2025-04-12 17:31:24《代号佳人》浪漫与冒险并存——2025年4月12日特别活动
- 2025-06-08 19:23:53捕盗行纪:迷雾之城的盗贼追踪
- 2026-01-02 04:50:04菱角烹饪时间与熟度揭秘
- 2025-04-26 09:39:21跨星系联合行动:星际探索模拟2025年度深空殖民者盛典启幕
- 2025-10-29 07:43:16王者荣耀s40赛季最强上分英雄汇总
- 2026-01-06 09:23:07世界上跑得最快的马,速度高达19米/秒,比汽车速度还快!
- 2025-04-28 02:16:24《龙甲情缘》2025年春季庆典:龙族觉醒与情缘共舞
- 2025-06-14 10:14:39石器总动员:2025年盛夏远古部落争霸赛暨全服狂欢庆典活动
- 2025-04-18 15:34:09《三国艳义》群英荟萃·跨服争霸盛典——2025年度全服巅峰之战荣耀启幕
- 2025-10-17 09:57:27【原】内存条在电脑中的作用是什么,我用大白话一次性说清楚
