异步守护进程处理/与Django的ORM交互
我想找一种方法,使用Django的ORM来进行异步数据处理,但问题是ORM本身不是线程安全的,也就是说在不同的线程中获取或修改Django对象是不安全的。所以我在想,怎样才能正确地实现异步处理呢?
简单来说,我需要做的是从数据库中获取一份用户列表,然后查询一个第三方的API,最后更新这些用户的个人资料。这一切都需要在后台进程中完成。逐个用户处理虽然简单,但速度太慢,根本无法扩展。如果这个后台进程通过ORM来获取和更新用户数据,我该如何一次处理10到20个用户呢?我本来想用标准的线程和队列系统来实现,但像
models.User.objects.get(id=foo) ...
这样的操作是不能在多线程中进行的。
Django本身是一个异步处理系统,对于每个请求都会进行异步的ORM调用,所以应该有办法做到这一点吧?不过到目前为止,我在文档中还没有找到相关的信息。
谢谢!
2 个回答
你可以看看celery这个工具。我觉得它能解决你的问题。它使用了多进程模块。虽然需要一点点设置,但在扩展方面会非常有帮助。
如果你的异步处理是在自己的进程中进行的,那么线程安全就不是问题了,因为这些线程并不共享同一个地址空间,所以它们不会互相干扰。每个线程都会有自己的一份模型对象。并发性会通过数据库的事务来控制,所以这样就没问题了。
但是,如果你打算在某个web服务器的进程里创建一个线程来处理异步业务,那么你需要对所有不安全的API调用进行锁定,以确保线程安全。
from threading import Lock
Apache通过fork()系统调用使用多个进程来处理同时的网页请求。这就是为什么Django的ORM API不需要线程安全的原因。我相信Apache也可以使用线程而不是进程,但我觉得要使用Django时这个功能必须被禁用。
http://groups.google.com/group/django-developers/browse_thread/thread/905f79e350525c95
顺便问一下,你知道线程和进程之间的区别吗?这个区别挺重要的。