我正在设置分布式芹菜环境以对PDF文件进行OCR。我有大约3M PDF和OCR是CPU绑定的,所以我们的想法是创建一个服务器集群来处理OCR。
在我编写任务时,我有这样的事情:
@app.task
def do_ocr(pk, file_path):
content = run_tesseract_command(file_path)
item = Document.objects.get(pk=pk)
item.content = ocr_content
item.save()
问题我有什么最好的方法是让file_path
在分布式环境中工作。人们通常如何处理这个问题?现在我的所有文件都只是存放在我们其中一台服务器上的一个简单目录中。
答案 0 :(得分:5)
如果您在linux环境中,最简单的方法是使用sshfs在群集中的/mnt
文件夹foreach节点中安装远程文件系统。然后,您可以将节点名称传递给do_ocr
函数,并且所有数据都是当前节点的本地数据
例如,您的群集有N个节点,名为:node1,...,nodeN
让我们配置node1,foreach节点挂载远程文件系统。这是node1的/ etc / fstab文件的示例
sshfs#user@node2:/var/your/app/pdfs /mnt/node2 fuse port=<port>,defaults,user,noauto,uid=1000,gid=1000 0 0
....
sshfs#user@nodeN:/var/your/app/pdfs /mnt/nodeN fuse port=<port>,defaults,user,noauto,uid=1000,gid=1000 0 0
在当前节点(node1)中创建一个名为当前服务器的符号链接,指向pdf的路径
ln -s /var/your/app/pdfs node1
您的mnt文件夹应包含远程文件系统和符号链接
user@node1:/mnt$ ls -lsa
0 lrwxrwxrwx 1 user user 16 apr 12 2016 node1 -> /var/your/app/pdfs
0 lrwxrwxrwx 1 user user 16 apr 12 2016 node2
...
0 lrwxrwxrwx 1 user user 16 apr 12 2016 nodeN
然后你的功能应该是这样的:
import os
MOUNT_POINT = '/mtn'
@app.task
def do_ocr(pk, node_name, file_path):
content = run_tesseract_command(os.path.join(MOUNT_POINT,node_name,file_path))
item = Document.objects.get(pk=pk)
item.content = ocr_content
item.save()
它的工作方式就像当前机器中的所有文件一样,但是远程逻辑可以透明地为您工作
答案 1 :(得分:2)
嗯,有多种方法可以处理它,但让我们坚持使用最简单的方法之一:
答案 2 :(得分:1)
由于我错过了很多您的架构详细信息和您的应用程序细节,因此您可以将此答案作为指导性答案而非严格的答案。 您可以按以下顺序采用此方法:
1-部署内部文件服务器,将所有文件存储在一个位置并提供服务
示例:
http://interanal-ip-address/storage/filenameA.pdf
依旧......
2-安装/部署Redis
3-创建一个上传客户端/服务/流程,它将获取您要上传的文件并将其传递到上述存储位置(/storage/
),以便您的文件在上传后可用,同时将完整文件路径URL推送到预定义的Redis列表/队列(构建在链接列表数据结构上),如下所示:http://internal-ip-address/storage/filenameA.pdf
您可以在Redis Lists
下方获取有关LPUSH和RPOP的详细信息:http://redis.io/topics/data-types-intro
示例:
4-现在我们来到您的芹菜工作者,您的每个工作人员应从Redis队列中提取(RPOP)其中一个文件URL,从内部文件服务器下载文件(我们在第一步中构建),并且按照您希望的方式进行所需的处理。
Redis文档中需要注意的一件重要事项:
列表具有使其适合实现的特殊功能 队列,通常作为进程间的构建块 通信系统:阻塞操作。
然而,有时列表可能是空的并且有 无需处理,因此RPOP只返回NULL。在这种情况下是消费者 被迫等待一段时间并再次使用RPOP重试。这就是所谓的 轮询,在这种情况下不是一个好主意,因为它有几个 缺点
因此Redis实现了名为BRPOP和BLPOP的命令,这些命令是版本 如果列表为空,RPOP和LPOP能够阻止它们:它们将返回 只有当一个新元素被添加到列表中时,或者当一个元素被添加到调用者时 达到用户指定的超时。
如果能回答你的问题,请告诉我。
要记住的事情
您可以根据需要添加任意数量的工作人员,因为此解决方案非常实用 可扩展,你唯一的瓶颈是Redis服务器,你可以在停电或服务器崩溃时建立集群并保持队列
您可以使用RabbitMQ,Beanstalk,Kafka或任何其他排队/消息系统替换redis,但由于简单性和开箱即用的无数功能,Redis已经在本次竞赛中获得提名。