目前我们把所有的东西都设置在一个云服务器上,包括:
- 数据库服务器Apache
- 芹菜
- redis作为芹菜和其他一些任务的代理 等
现在我们正在考虑将主要组件拆分到单独的服务器上,例如单独的数据库服务器,单独的媒体文件存储,负载均衡器后面的web服务器。原因是不需要为一个沉重的服务器付费,而是使用负载平衡器按需创建服务器,以降低成本并提高整体速度。
我真的对芹菜感到困惑,有人曾经在负载平衡器后面的多个生产服务器上使用芹菜吗?如有任何指导,将不胜感激。
考虑一个小的用例,这是目前如何在单台服务器上完成的(混淆是当我们使用多台服务器时如何完成):
- 用户上传
abc.pptx
文件->引用存储在数据库->存储在服务器磁盘 - 创建一个任务(将文档转换为pdf)并进入redis (broker)队列 在同一服务器上运行的
- 芹菜从队列中选择任务
- 读取文件,使用
docsplit
软件将其转换为pdf - 在服务器磁盘上创建一个文件夹(稍后将用作静态内容),将pdf文件及其缩略图和纯文本以及原始文件
- 读取文件,使用
考虑到上面的用例,如何设置多个可以执行相同功能的web服务器?
将极大地简化处理过程的是一些共享存储,可以从所有合作的服务器访问。有了这样的设计,您可以将工作分配到更多的服务器上,而不必担心下一个处理步骤将在哪个服务器上完成。
使用AWS S3(或类似)云存储
如果你可以使用一些云存储,比如AWS S3,那就使用它。
如果您的服务器也在AWS上运行,则无需为同一区域内的流量付费,并且传输速度相当快。
主要优点是,您的数据可以从相同桶/密钥名称下的所有服务器上获得,因此您不必担心谁在处理哪个文件,因为所有服务器都在S3上共享存储。
注意:如果你需要删除旧文件,你甚至可以在给定的bucket上设置一些策略文件,例如删除超过1天或1周的文件。
使用其他类型的共享存储
有更多的选项
- Samba
- 中央文件服务器 FTP
- Google存储(非常类似于AWS S3)
- Swift(来自OpenStack)
- 等。
对于小文件,你甚至可以使用Redis,但这样的解决方案是有充分理由的,相当罕见。
芹菜实际上使这非常简单,因为您已经将任务放在队列中。有了更多的工人,所有的变化是每个工人取队列上的下一个,所以多个工人可以同时处理,每个人在自己的机器上。
这有三个部分,你已经知道了其中的一个。
- 共享存储,以便所有机器都可以访问相同的文件
- 一个可以将任务分发给多个worker的broker - redis是很好的
- 在多台机器上工作
设置方法如下:
- 用户将文件上传到前端服务器,前端服务器存储在共享存储(例如S3、Samba、NFS等)中,并将引用存储在数据库 中。
- 前端服务器启动一个芹菜任务来处理文件,例如
def my_view(request):
# ... deal with storing the file
file_in_db = store_file(request)
my_process_file_task.delay(file_in_db.id) # Use PK of DB record
# do rest of view logic...
- 在每台处理机上运行celery-worker:
python manage.py celery worker --loglevel=INFO -Q default -E
当你添加更多的机器时,你将有更多的工人,工作将在他们之间分配。
注意事项:
- 你必须有共享存储,否则这会变得更复杂
- 每个工作机器必须有正确的Django/芹菜设置,以便能够找到redis代理和共享存储(例如S3桶,密钥等)