pythonrq:回调模式
我现在有大量文档要处理,并且正在使用PythonRQ来并行化任务 我想一个管道的工作要做的不同的操作是对每个文件执行。例如:pythonrq:回调模式,python,parallel-processing,python-rq,Python,Parallel Processing,Python Rq,我现在有大量文档要处理,并且正在使用PythonRQ来并行化任务 我想一个管道的工作要做的不同的操作是对每个文件执行。例如:A->B->C表示将文档传递给函数A,在A完成后,继续执行B并最后执行C 然而,pythonrq似乎并没有很好地支持管道 下面是一个简单但有点脏的方法。总之,管道中的每个函数都以嵌套方式调用其下一个函数 例如,对于管道a->B->C 在顶层,一些代码是这样编写的: q.enqueue(A,文档) 其中q是队列实例,在函数A中有如下代码: q.enqueue(B,文档) 在B
A
->B
->C
表示将文档传递给函数A
,在A
完成后,继续执行B
并最后执行C
然而,pythonrq似乎并没有很好地支持管道
下面是一个简单但有点脏的方法。总之,管道中的每个函数都以嵌套方式调用其下一个函数
例如,对于管道a
->B
->C
在顶层,一些代码是这样编写的:
q.enqueue(A,文档)
其中q是队列
实例,在函数A
中有如下代码:
q.enqueue(B,文档)
在B
中,有如下内容:
q.enqueue(C,文档)
还有比这更优雅的方式吗?例如,ONE函数中的某些代码:
q.enqueue(A,文档)
q、 排队(B,_doc,after=A)
q、 排队(C,文档,后面=B)
参数是与我的需求最接近的参数,但是,运行类似于:
A_job=q.enqueue(A,_doc)
q、 排队(B,取决于=A作业)
不行。由于q.enqueue(B,dependens\u=A\u job)
在执行A\u job=q.enqueue(A,the\u doc)
后立即执行。当B排队时,A的结果可能还没有准备好,因为它需要时间来处理
附言:
如果Python RQ在这方面并不擅长,那么我还可以使用Python中的其他工具来达到同样的目的:
它不支持开箱即用,但使用其他技术是可能的 在我的例子中,我使用缓存来跟踪链中的前一个作业,因此当我们想要将一个新函数排队(在之后立即运行)时,我们可以在调用enqueue()时正确设置其“depends_on”参数 注意使用附加参数排队:超时,结果\u ttl,ttl'。因为我在rq上运行长作业,所以使用了这些。您可以在pythonrq文档中引用它们的用法 我使用了django_rq.enqueue(),它是从 “取决于”-来自: 依赖-指定必须完成的另一个作业(或作业id) 在此作业将被排队之前 当B排队时,A的结果可能还没有准备好,因为它需要时间来处理 我不确定当你最初发布问题时这是否是真的,但无论如何,现在这不是真的。事实上,
dependens\u on
功能正是为您描述的工作流而设计的
的确,这两个功能会立即连续执行
A_job = q.enqueue(A, the_doc)
B_job = q.enqueue(B, depends_on=A_job )
但是在A
完成之前,工作人员不会执行B
。在A_作业
成功执行之前,B.status=='deferred'
。一旦A.status==“finished”
,则B
将开始运行
这意味着B
和C
可以访问和操作其依赖关系的结果,如下所示:
导入时间
从rq导入队列中,获取当前作业
从redis导入StrictRedis
conn=StrictRedis()
q=队列('高',连接=连接)
定义A():
时间。睡眠(100)
返回“结果A”
def B():
时间。睡眠(100)
当前作业=获取当前作业(conn)
a\u job\u id=当前的\u job.dependencies[0].id
a_job_result=q.fetch_job(a_job_id)。result
断言一个_作业_结果==“结果a”
返回作业结果+结果B
def C():
时间。睡眠(100)
当前作业=获取当前作业(conn)
b_作业\u id=当前作业。依赖项[0]。id
b_job_result=q.fetch_job(b_job_id)。result
assert b_job_result=='result A result b'
返回b_作业结果+“结果C”
工作人员最终将打印“结果A结果B结果C”
此外,如果队列中有许多作业,并且B
在执行之前可能要等待一段时间,则可能需要显著增加result\u ttl
或使用result\u ttl=-1使其不确定。否则,在为result\u ttl
设置了多少秒后,A的结果将被清除,在这种情况下B
将无法再访问它并返回所需的结果
然而,设置result\u ttl=-1
具有重要的内存含义。这意味着您的作业结果将永远不会自动清除,并且内存将按比例增长,直到您从redis手动删除这些结果。使用3个队列如何?一个用于作业a,另一个用于作业b,最后一个用于作业c,唯一的问题是当作业a结束时,文档在作业b队列中排队,依此类推…即使q.enqueue(b,dependens\u=a\u job)
作业b将在a结束后处理。重要的不是它什么时候处理而不是排队吗?@Marcel使用3个队列与使用单个队列有何不同?它将如何解决这个问题?你找到答案了吗?在每个作业中添加睡眠的目的是什么?@user24
A_job = q.enqueue(A, the_doc)
B_job = q.enqueue(B, depends_on=A_job )