前言
本篇文章介绍一下python的两种分布式框架,一种是rq,另一种是ray。使用分布式可以处理大量的并发且耗时的操作。
一、RQ框架
1.1 rq介绍
RedisQueue是一款轻量级的分布式异步任务队列调度框架,基于redis数据库作为broker,生产端将任务job存储到redis数据库中,消费端监听队列并取出任务执行。
1.2 安装
pip install rq
1.3 生产端
from rq import Queue
import redis
def count_read_files(file):
f = open(file)
lines = f.read()
f.close()
return count(lines)
conn = redis.Redis(host='127.0.0.1', password='xxxxxx', port=6379, db=1)
q = Queue("file", connection=conn)
file_list = ["a.txt", "b.txt", "c.txt"]
for file in file_list:
q.enqueue_call(count_read_files, args(file,))
1.4 消费端
import redis
from multiprocessiong import Pool
from rq import Worker, Queue, Connection
conn = redis.Redis(host='127.0.0.1', password='xxxxxx', port=6379, db=1)
def worker(listen):
with Connection(conn):
worker = Worker(map(Queue, listen))
worker.work()
def run(num, listen):
try:
p = Pool(num)
for i in range(num):
p.apply_async(worker, args=(listen,))
p.close()
p.join()
except Exception as e:
print(e)
if __name__ == "__main__":
listen = ["file", "don", "image"]
cpu_num = 4
run(cpu_num, listen)
1.5 redis集群
from rq.cli.helpers import get_redis_from_config
settings = {'SENTINEL': {
'INSTANCES': [('redis1.cloud.bz', 6379),
('redis2.cloud.bz', 6379),
('redis3.cloud.bz', 6379)],
'SOCKET_TIMEOUT': None,
'PASSWORD': 'xxxxxx',
'DB': 1,
'MASTER_NAME': 'sentinel-127.0.0.1-6379'
}
}
conn = get_redis_from_config(settings)
二、Ray框架
2.1 介绍
Ray是UC Berkeley RISELab新推出的高性能分布式执行框架,它使用了和传统分布式计算系统不一样的架构和对分布式计算的抽象方式,具有比Spark更优异的计算性能
但是目前只要Linux下的编译版本,Windows暂时无法使用。
2.2 安装
pip install ray
2.3 示例
import ray
ray.init()
@ray.remote
def who():
return "xiao ming"
obj_id = who.remote()
name = ray.get(obj_id)
print(name)
"""
在Ray里,通过Python注解@ray.remote定义remote函数。使用此注解声明的函数都会自带一个默认的方法remote,通过此方法发起的函数调用都是以提交分布式任务的方式异步执行的,函数的返回值是一个对象id,使用ray.get内置操作可以同步获取该id对应的对象。
"""
import ray
ray.init()
@ray.remote
def num_one():
return "one"
@ray.remote
def num_two():
return "two"
@ray.remote
def add(one, two):
res = one + two
return res
one_id = num_one.remote()
two_id = num_two.remote()
add_id = add.remote(one_id, two_id)
print(ray.get(add_id))
"""
例子代码中,对函数num_one、num_two的调用是完全并行执行的,但是对函数add的调用依赖于num_one、num_two函数的返回结果。Ray可以保证函数add需要等待num_one、num_two函数的结果真正计算出来后才会执行。
这样可以解决在异步中,某一部分依赖另一部分的结果问题。
"""
2.4 Ray集群
ray.init(redis_address="xxx.xxx.x.x")
2.5 常用方法
ray.put()
"""
可以将Python对象存入本地ObjectStore,并且异步返回一个唯一的ObjectID。通过该ID,Ray可以访问集群中任一个节点上的对象
"""
ray.get()
"""
可以通过ObjectID获取ObjectStore内的对象并将之转换为Python对象。对于数组类型的对象,Ray使用共享内存机制减少数据的拷贝成本。而对于其它对象则需要将数据从ObjectStore拷贝到进程的堆内存中。
如果调用ray.get()操作时,对象尚未创建好,则get操作会阻塞,直到对象创建完成后返回。
"""
result_ids = [ray.put(i) for i in range(10)]
ray.get(result_ids)
ray.wait()
"""
支持批量的任务等待,基于此可以实现一次性获取多个ObjectID对应的数据
"""
results = [f.remote(i) for i in range(5)]
ready_ids, remaining_ids = ray.wait(results, num_returns=4, timeout=2500)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律