排除瓶颈和加速django项目
博客专区 > 好铁 的博客 > 博客详情
排除瓶颈和加速django项目
好铁 发表于1年前
排除瓶颈和加速django项目
  • 发表于 1年前
  • 阅读 8
  • 收藏 0
  • 点赞 0
  • 评论 0

移动开发云端新模式探索实践 >>>   

作者: Desmond Chen

本篇中我们介绍一些基本的查找和加速django项目的策略.

1. 先等等

首先我们需要明白, 错误的优化不是什么好事. 如果你的项目只是小到中等规模, 并且加载速度过得去, 那么你完全没有必要进行优化.

如果你项目的用户在持续稳定的增加, 并且达到了一定的数目, 那么请往下看.

2. 加速Query查询

如果一个页面中query数太多, 或一个query得到的数据太大, 都会导致加载速度变慢. 首先你可以看一下Django官网关于数据库优化的文档: https://docs.djangoproject.com/en/1.9/topics/db/optimization/.

a. 使用django-debug-toolbar

django-debug-toolbar可以找到query的来源, 并且找到:

  • 重复的query
  • 产生大量query的ORM语句
  • 慢query

你对哪些页面载入较慢应该有个大致的了解, 所以你只需要使用django-debug-toolbar打开这些页面, 查看是哪些query拖慢了整体速度.

b. 减少query数

一旦找到了哪些页面包含过多的query数后, 我们便可以采取措施减少query数:

  • 在ORM中使用select_related()减少query数: 使用select_related()会自动扩展外键关系, 将外键中的数据提前合并到本次query. 如果使用CBV, django-braces的SelectRelatedMixin达到同样的目地. 但要小心query扩展的过深.
  • 如果同样的query发生多次, 那么将其移到view中, 在使用context将其传到template中.
  • 使用redis等caching, 然后测试.
  • 使用django.utils.functional.cached_property修饰器, 将query结果cache在内存中.

c. query提速

获取一个大的query结果同样也会影响速度, 因此我们首先需要:

  • 确保index起到了加速query的作用
  • 理解在部署服务器中index的作用, 分析理解数据库中真正发生了什么
  • 查看ORM生成的raw SQL语句
  • 开启数据库的 slow query logging功能, 并查看慢query发生的频率
  • 使用django-debug-toolbar找到慢query

然后我们便可以:

  • 重写代码, 使query获得更小的片段
  • 重写代码, 使query更好的利用index
  • 使用raw SQL语句代替ORM生成的慢SQL语句

d. ATOMIC_REQUESTS选项

大多数django项目在ATOMIC_REQUESTS=True的状况下运行都没有什么问题. 如果你的瓶颈分析显示数据库transaction导致了延迟, 那么你可以选择将ATOMIC_REQUESTS=False

3. 数据库优化

除了以上提到的query优化外, 你可以更进一步的进行数据库优化, 相信这方面的书或文章已经很多了, 我们不进行深入讨论了. 主要是以下几点:

a. 哪些不属于数据库

有两种数据不应该储存在数据库中, 一个是log信息, 另一个则是经常变化的数据. log信息在开发时看似没有什么影响, 但在正式服务器上运行时, 可能会拖慢数据库, 因此我们建议使用Splunk, Loggly这样的第三方服务或使用NoSQL数据库保存这些数据. 经常变换的数据比如django.contrib.sessions, django.contrib.messages等应尽量保存到Memcached, Redis, Riak或其他NoSQL数据库中.

b. PostgreSQL

对于postgres, 在正式服务器中一定要保证设置正确. 具体的设置方法可以自行google之. 还可以参考书 "Postgresql 9.0 high performance".

c. MySQL

MySQL容易安装和运行, 但如何优化需要长时间的经验和理解. 我们推荐书"high performance MySQL".

4. 使用Memcached或Redis进行Query Cache

你可以使用Django自带的caching系统配合Memcached或Redis, 轻松的完成整站cache的配置. 也可以使用Django的Low-level API完成复杂的设置.

重要的是, 你需要确定哪些需要cache, 哪些不需要cache. 你需要考虑, 哪些view/template包含的query最多? 哪些URL被浏览的最多? 被cache的页面何时需要失效处理?

我们也可以使用第三方package: 比如django-cache-machine, johnny-cache等.

5. 最小化HTML, CSS和JavaScript文件

当浏览器呈现网页时, 必须载入HTML, CSS, JavaScript和图片. 所有这些文件都会消耗用户的带宽, 使浏览速度下降. 虽然Django自带了GZipMiddleware和{% spaceless %} template tag, 还有WSGI的 middleware都能帮助我们减小这些文件. 但使用以上方法都会增加Django自身的系统资源占有量, 可能会导致瓶颈. 最好的方式则是将这一操作交给Apache或Nginx这些web server, 比如利用PageSpeed Module.

当然django的第三方package来压缩和最小化CSS和JavaScript文件也是可行的, 常见的插件有django-pipeline, django-compressor, django-htmlmin等.

6. 使用Upstream caching或CDN

使用Varnish等upstream caching也能加快系统的载入速度. 当然我们还可以AWS等云服务部署自己的CDN, 为全球的用户提供快速的图片, 视频, CSS文件和JavaScript的载入.

 

原文链接: http://www.weiguda.com/blog/33/

标签: Django Python
  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 34
博文 264
码字总数 78066
×
好铁
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: