在Mod_WSGI中使用Django缓存
有没有人知道在用Apache/Mod_WSGI部署Django的缓存框架时会出现什么问题吗?
我在本地用开发服务器测试缓存框架时,使用了性能分析中间件和FileBasedCache或LocMemCache,Django的速度非常快。我的请求时间从大约0.125秒降到了0.001秒,真是太棒了。
但是,当我把相同的代码部署到一个运行Apache/Mod_WSGI的远程机器上时,请求时间从大约0.155秒(部署前)变成了0.400秒(部署后)。没错,缓存反而让一切变慢了。
我花了好几个小时在各种地方查找,想看看是不是漏掉了什么。我尝试过在tmpfs上使用FileBasedCache,但也没有改善性能。
我监控了远程机器,发现没有其他进程在运行,而且有6GB的可用内存,所以基本上Django应该可以尽情使用资源。我非常喜欢Django,但它实在是太慢了,到现在为止我还没能让缓存框架在生产环境中产生任何明显的效果。我是不是漏掉了什么?
补充:我也试过memcached,结果也是一样。我通过telnet确认了memcached正在运行。
3 个回答
我也遇到过同样的问题,想知道是什么东西耗费了这么多时间。每次获取缓存大约要花100毫秒。
于是我调试了Django的本地内存缓存代码,发现是pickle这个过程花了很多时间(我把整个表都缓存到了本地内存中)。我把本地内存缓存包了一下,因为我不想用什么复杂的东西,所以即使你去掉pickle的过程,直接存和取数据,你也会看到明显的速度提升。
希望这对某些人有帮助。
我之前也遇到过一个类似的问题,那个应用是用memcached的。解决办法是把mod_wsgi设置成守护进程模式,而不是嵌入模式,同时把Apache设置成mpm_worker模式。这样一来,应用的运行速度就快多了。
确实,Django的速度比较慢。不过我得说,大部分慢的原因其实是应用本身的问题。Django在文档中给出了一些不太好的示例,导致你不得不使用一些在生产环境中表现不佳的懒惰方式。
首先,试试用nginx加上uwsgi。这组合真的是最好的选择。
要优化你的应用,你需要找出导致慢的原因,可能是:
- 数据库查询慢(可能是查询太多,或者某些查询本身就慢)
- 数据库本身慢
- 文件系统慢(比如使用nfs)
可以尝试记录请求的查询,并观察一下iostat或iotop之类的工具。
我之前用apache加mod_wsgi遇到过这样的情况:第一次从浏览器发请求时非常慢……然后同一个浏览器的后续请求就快了很多……但如果我不操作两分钟后,再次请求又会变得很慢。我不知道是不是apache配置不当,导致它每次keepalive请求都要重新启动wsgi应用。这让我很烦,所以我换成了nginx,结果用nginx加fgci后,速度比apache加mod_wsgi快多了。