Ray_异步执行数据_pipeline
Ray Core
Ray Core:Ray 的核心调度和分布式执行引擎,负责任务调度、资源管理、对象存储等
核心抽象和核心方法:
Ray的架构包括(1)一个实现API的应用层(2)一个提供高可伸缩性和容错能力的系统层
3个核心抽象
Task、Actor 和Object的
6个核心方法
ray.init() 初始化集群,
@ray.remote 负责把函数或类变成任务或Actor
ray.put() 和 ray.get() 负责数据的存储和读取
.remote() 用来执行任务或Actor方法
ray.wait() 用来处理异步等待。
抽象:
单机编程中经常用到两个非常核心的概念,一个叫Function,一个叫Class,
对应到分布式系统就叫Task和Actor 分布式的对象存储能力 Task计算的中间结果会存放在分布式Object Store
Object有两种创建的方法,一种是通过Task返回,每个Task的返回结果(只要大于一定阈值,默认为100KB)都会存储在本地的对象存储当中;
另一种是使用ray.put()显式地创建
方法
.remote()返回的是一个future对象
底层机制
Ray通过事件总线(EventBus)和事件订阅机制来实现任务的异步处理和状态一致性。
Ray支持状态(State)、事件(Event)和事件总线(EventBus)的概念,通过这些机制来管理任务的执行和状态变
中两类关键的节点:头节点(Head)和工作节点(Worker)。这些节点可以部署在虚拟机、容器或者是裸金属服务器上
Head: Global Control Service(GCS) GCS 是 Ray 集群的全局元数据管理服务
Driver Job Raylet(Raylet 主要包含两个组件:一个是调度器(Scheduler),它负责资源管理和任务分配;
另一个是基于共享内存的对象存储(Shared-memory Object Store))
Worker: Driver Job Raylet(Raylet 主要包含两个组件:一个是调度器(Scheduler),它负责资源管理和任务分配;另一个是基于共享内存的对象存储(Shared-memory Object Store))
ray 集群是由一个或者多个 worker 节点组成,每个 worker 节点由以下物理进程组成
ray start --head --port=6379
ray start --address=<head-node-address>:<port>
示例代码
import ray
###初始化集群,
ray.init()
### 负责把函数或类变成任务或Actor
@ray.remote
def slow_square(x):
import time; time.sleep(1)
return x * x
### .remote() 用来执行任务或Actor方法
futures = [slow_square.remote(i) for i in range(10)]
### ray.put() 和 ray.get() 负责数据的存储和读取
results = ray.get(futures)
print(results)
分布式节点
Ray在每个工作节点上启动任务或Actor时,会自动基于给定的环境配置创建一个具有相同Python依赖的新环境,从而确保models等模块在所有节点上都能正确导入
runtime_env =
# 在ray.init()中设置runtime_env
ray.init(
include_dashboard=False,
address="172.17.0.6:6389",
runtime_env={
"env_vars": {
"RESOURCE_DIR": "/workspace/client/fedwav2vec2",
},
"conda": {
"dependencies": ["file:requirements.txt"], # 指向你的conda或pip依赖文件
},
},
)
有没有反压--没有反压的例子
ray.wait(objects, num_returns=1, timeout=None)
num_returns: (可选)指定要返回的完成对象的数量。默认为 1。
num_returns表示最多返回 已经ready的
ray.wait() 返回一个元组,其中包含两个列表: ready: 完成的对象列表 unready: 还未准备好的对象列表
调优
延迟获取:尽可能推迟ray.get()调用以保持并行度
任务聚合:避免微任务,确保每个远程任务有足够工作量
对象复用:对大对象预先调用ray.put(),传递ID而非对象本身
流水处理:使用ray.wait()实现结果处理的流水线化
集群调度、资源管理
异步的方式在Ray集群的Workers上远程运行
Ray项目跨语言编程
掌握Python与Java互调的基本方法
Ray提供了Error Catch机制、Retry机制来处理应用层面的错误
异步编程是一种编程范式
python async/await和asyncio包 事件循环(Event Loop)是异步编程中负责管理和调度异步任务执行的机制
分布式框架
Ray 是一个开源的分布式系统框架,用于并行和分布式Python代
不直接依赖消息系统
celery 使用消息服务: 通常使用RabbitMQ或Redis作为消息代理。
Celery是一个异步任务队列/作业队列,基于分布式消息传递。它专注于实时处理,同时也支持任务调度。
zeroMQ
过Flask Web接口调用Celery定时任务,并探讨了使用Redis和RabbitMQ的区别,以及如何配置Celery worker、beat和任务注册
Celery由以下三部分构成:消息中间件(Broker)、任务执行单元Worker、结果存储(Backend)
区别和联系
celery也是一个分布式计算的框架。但是celery部署work进程时候, 需要制定 task所在脚本,
这样工作进程的环境部署,是跟要执行的脚本强相关的。
Ray,更加类似Jenkins的主从模式, 可以将待执行的脚本推送到worker node上,然后执行,这在应用部署上更加解耦,
ray相当于是一个分布式运行环境, 可以提交任何的脚本到平台上执行。类似 spark 平台。
分布式计算框架Spark和Ray而闻名
部署和维护
supervisor
相同点和区别
相同点
并发处理:四种方法都可以实现并发处理,提高任务执行效率。
异步执行:都支持异步执行任务,避免阻塞主线程。
区别
适用场景:
线程池:适合处理I/O密集型任务,简单易用,但不适合CPU密集型任务。
Ray:适合处理CPU密集型和I/O密集型任务,支持分布式环境。
Celery:适合处理大量的任务,支持分布式环境和任务调度。
asyncio:适合处理大量的I/O密集型任务,轻量级。
配置复杂度:
线程池:配置简单。
Ray:配置相对复杂。
Celery:配置和使用相对复杂。
asyncio:需要一定的异步编程经验。
资源开销:
线程池:资源开销较小。
Ray:在单机环境下可能会引入额外的资源开销。
Celery:在单机环境下可能会引入额外的资源开销。
asyncio:资源开销最小。
性能差异
线程池:在I/O密集型任务中表现良好,但在CPU密集型任务中由于GIL限制,性能受限。
Ray:在CPU密集型和I/O密集型任务中表现良好,适合分布式环境。
Celery:在处理大量任务时表现良好,适合分布式环境和任务调度。
asyncio:在I/O密集型任务中表现最佳,适合高并发场景。
文件系统
文件系统
fsspec,全称为 Python Filesystem Specification
文件格式
Parquet,一种持久化异构列式数据集的文件格式
pyarrow
文件压缩
Zstandard(简称zstd)是由Facebook开发并维护的开源项目,主要使用C语言编写。
该项目旨在提供一种快速、高效的实时压缩算法,适用于各种需要高压缩比和快速解压缩的场景
Zstandard不仅支持其专有的.zst文件格式,还支持解压缩.gz、.xz和.lz4文件格式
计算机性能
psutil是一个跨平台库能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。
它主要用来做系统监控,性能分析,进程管理
参考
Ray项目新手使用指南:四大核心优化技巧 https://blog.csdn.net/gitblog_01046/article/details/148325894
Ray设计模式:使用ray.wait限制任务并发提交数 https://zhuanlan.zhihu.com/p/3680163842
线程池、Ray、Celery 和 asyncio 的比较 https://blog.csdn.net/m0_51738372/article/details/148386953
https://scale-py.godaai.org/ch-parallel-computing/computer-architecture.html

浙公网安备 33010602011771号