文档章节

排除瓶颈和加速django项目

好铁
 好铁
发布于 2017/04/04 21:19
字数 1280
阅读 19
收藏 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/

本文转载自:http://www.weiguda.com/blog/33/

共有 人打赏支持
好铁
粉丝 35
博文 266
码字总数 78672
作品 0
朝阳
程序员
Django之部署NGINX+uWSGI

参考地址:http://www.cnblogs.com/CongZhang/p/6548529.html http://www.cnblogs.com/alex3714/p/6538374.html http://uwsgi.readthedocs.io/en/latest/tutorials/Djangoandnginx.html ----......

LinQiH
2017/11/07
0
0
编程零基础应当如何开始学习 Python ?

提前说一下,这篇福利多多,别的不说,直接让你玩回最有手感的怀旧游戏,参数贴图很方便自己可以根据喜好修改哦。 本篇通过以下四块展开,提供大量资源对应。 【选一个好版本 有没有看过《在...

崔斯特呀
2017/09/14
0
0
Django 静态资源管理利器:django-pipeline

django-pipeline 是一个 Django 下非常方便的静态资源管理 app,尤其是 1.2 版本之后,利用 的 命令,在开发、部署环境下切换非常方便。 写 codinn.com 代码的时候,静态资源管理方面遇到了一...

索隆
2012/07/16
0
0
django1.8+uwsgi+nginx+supervisord部署项目笔记

学这个搞了我2天。最好的东西学会了怎排除问题。 直接贴代码,我同时部署2个项目,一个直接返回' hello',另一个空。 hello 项目: /root/27env/hello/uwsgi.ini: #########################...

NLGBZJ
2015/10/12
486
0
Django + Uwsgi + Nginx 实现生产环境部署

今天老男孩IT教育Python教学导师吴sir带你用Django + Uwsgi + Nginx 实现生产环境部署 1、uwsgi 介绍 2、uwsgi安装使用 3、nginx安装配置 4、django with nginx 如何在生产上部署Django? Dja...

米斯特赛文
2017/04/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

负载均衡的解决方案有哪些

负载均衡器服务可满足大型组织的需求,支持所有数据中心和跨数据中心高可靠性场景。 本地负载均衡,通过附带或者未附带持久性覆盖选项,Incapsula支持各种负载均衡算法,以优化服务器之间的流...

上树的熊
12分钟前
0
0
Java实现在线打开word文档加盖印章/盖章/签名功能

前言: 我们知道,大型一点的OA办公系统都会有很多在线处理office办公文档的需求。其中有一点也基本绕不开,那就是为文档盖章或添加手写签名来保护文档,让被盖章的文档不再被编辑。 在Java中...

山里的红杏
20分钟前
3
0
js控制输入正负数,小数点后保留两位

//限制数字function clearNoNum(obj){ //修复第一个字符是小数点 的情况. if(obj.value !=''&& obj.value.substr(0,1) == '.'){ obj.value=""; } obj.value ...

一直在成长的程序猿
23分钟前
1
0
动态代理

具体场景 为了使代理类与被代理类对第三方有相同的函数,代理类与被代理类一般实现一个公共的interface,定义如下 public interface Subject { void rent(); void hello(String s)...

wuyiyi
26分钟前
0
0
时间字段

我们看看这几个数据库中(mysql、oracle和sqlserver)如何表示时间 mysql数据库:它们分别是 date、datetime、time、timestamp和year。date :“yyyy-mm-dd”格式表示的日期值 time :“hh:...

DemonsI
28分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部