异步进程生成:设计问题 - Celery还是Twisted

6 投票
3 回答
1719 浏览
提问于 2025-04-16 09:37

大家好:我在寻找一些建议和设计思路。我的目标是找到一种简单但可靠的方法,从HTTP POST请求中获取XML数据(这部分没有问题),解析它,然后异步启动一个相对长时间运行的进程。

这个启动的进程会消耗很多CPU资源,大约会持续三分钟。我一开始不期待会有太大的负载,但随着流量的增加,我很可能需要在多个服务器上扩展这个进程。

我非常喜欢使用Celery和Django这个组合来实现这个目标:它非常直观,并且有很多内置的框架可以满足我的需求。我开始时非常热情,但很快发现我的512MB内存的云服务器只有100MB的可用内存,一想到等我所有进程全速运行时可能会出问题,我就开始担心了。此外,这个组合有很多组件:RabbitMQ、MySQL、celeryd、lighttpd和Django容器。

我当然可以增加服务器的配置,但我希望在项目的早期阶段尽量降低成本。

作为替代方案,我在考虑使用Twisted来管理进程,以及在需要时使用Perspective Broker来处理远程系统。不过对我来说,虽然Twisted非常出色,但我感觉这条路会让我承担很多责任:需要编写协议、管理回调、跟踪任务状态等等。这里的好处很明显——性能优秀,组件更少,内存占用也更小(注意:我需要确认内存部分)。我非常倾向于使用Python,因为这让我觉得比其他选择更愉快 :)

我非常希望能听到大家的看法。我担心一开始就走错了方向,以后在面对生产流量时重新做会很痛苦。

-Matt

3 个回答

0

我再补充一个可能性:使用Redis。现在我用Redis和Twisted一起工作:我把任务分配给工作者,他们异步地完成任务并返回结果。

Redis中的“列表”类型非常有用: http://www.redis.io/commands/rpoplpush

你可以使用可靠队列模式来发送任务,并让一个进程阻塞/等待,直到有新的任务要做(也就是有新消息进到队列里)。

你可以在同一个队列上使用多个工作者。

Redis占用的内存很少,但要注意待处理消息的数量,这会增加Redis使用的内存。

0

我来回答这个问题,就像我是做这个项目的人,希望能给你一些启发。

我正在做一个项目,需要用到一个队列,一个面向公众的网页服务器,还有几个处理工作的客户端。

这个想法是让网页服务器一直运行(这里不需要特别强大的机器)。不过,实际的工作是由这些客户端来处理,它们是更强大的机器,可以随时启动和停止。工作队列也会放在和网页应用程序同一台机器上。当有工作被放入队列时,就会启动一个进程来启动这些客户端,并且会先启动第一个客户端。通过使用负载均衡器,可以在工作量增加时自动启动新的服务器,这样我就不用担心处理队列中工作的服务器数量。如果过了一段时间队列里没有工作了,所有的客户端都可以关闭。

我建议使用类似这样的设置。你不想让工作执行影响到你的网页应用程序的性能。

5

在我的系统上,RabbitMQ运行得还不错,大约只用2MB的内存。Celeryd用的稍微多一点,但也不算太多。

我觉得,RabbitMQ和Celery的开销相比其他部分来说几乎可以忽略不计。如果你处理的任务需要几分钟才能完成,那么这些任务才是当流量增加时会让你的512MB服务器吃不消的原因,而不是RabbitMQ。刚开始使用RabbitMQ和Celery,至少能让你在横向扩展这些任务时走上正确的道路。

当然,你可以在Twisted里自己写一个任务控制系统,但我觉得这样做没什么太大意义。Twisted的性能还不错,但我不认为它能比RabbitMQ快到值得你花时间去重写的地步,而且这样做可能还会引入bug和架构上的限制。总的来说,这似乎不是一个需要优化的地方。与其花时间重写RabbitMQ,不如花点时间把那些三分钟的任务缩短20%之类的。或者,干脆每月多花20美元,直接把你的服务器容量翻倍。

撰写回答