Django 优化杂谈

Apr 21 2017

总结下最近看过的一些文章,然后想到的一些优化点,整理一下.

数据库连接池

http://mt.dbanotes.net/arch/instagram.html

Django 默认DB配置提供了选项CONN_MAX_AGE用于配置在同一个thread/greenlet里面DB connection的最大存活时间,便于连接的复用,在实践中发现如果使用gunicorn+gevent的方式来启动WSGI服务,由于gunicorn会创建一个很大的gevent pool,导致数据库连接数会暴涨.所以这个选项被放弃了,另外的方式是使用connection pool.

instagram 使用 PostGreSQL 并且使用 Pgbouncer 这个中间件来管理连接池,MySQL也有Proxy这种中间件但是比较重,所以考虑在django mysql backend的基础上自己实现一个连接池.

https://gist.github.com/zhu327/94c22c7fa9c92cc38e998eab41e77c38

主要参考了Connector/Python的pool实现.

数据库连接池也不是”银弹”,在应用层做数据库连接池也不值得推荐,随着业务的扩展,使用一主多备搭建集群,通过读写分类中间件来做连接池管理,推荐ProxySQL.

缓存一切

https://mozillazg.github.io/2015/09/high-performance-django-note-1.html

从服务器的角度来看,我们可以用Nginx cache/Varnish来缓存响应.这里我们只讨论django cache framework.

我们的系统中使用redis作为缓存服务器,使用redis-py与django-redis作为cache backend.

redis-py是纯python实现的,查看了文档后发现它也支持使用一个C客户端的python绑定,只需要安装hiredis-py即可使用C解析器提升redis性能.

redis-py是自带connection pool支持的,默认使用redis.connection.ConnectionPool,连接数较多的情况下可能导致连接不够用抛出异常,可以考虑用redis.connection.BlockingConnectionPool替换,无连接可用时阻塞.

Session

Django 默认的 Session Engine 用的是数据库,因为Session中间件的缘故,每个请求进来都会首先访问Session表.我们可以用缓存来替代这个数据库访问的过程,推荐配置SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'即用了缓存,又保存到db保证数据不丢失.

Django 的 session 表在一段时间以后会数据会变得很大,需要定时执行python manage.py clearsessions来清理过期session.

缓存Model

https://github.com/rosarior/awesome-django

awesome-django有一些用户缓存的工具,翻过一些文档后决定引入django-cache-machine

  • 访问频繁读多写少的Model要缓存
  • 写多读少的Model酌情缓存(写的时候更新缓存开销大)

日志

Python的日志是同步的,所以如果直接把日志写入文件,也会有文件系统I/O的开销,更快的方式是把日志记录到sys.stderrsys.stdout,然后用gunicorn把标准输出的日志重定向到文件.

# 日志配置
import logging, logging.config
import sys LOGGING = {
'version': 1,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'stream': sys.stdout,
}
},
'root': {
'handlers': ['console'],
'level': 'INFO'
}
}

  

gunicorn选项:

http://docs.gunicorn.org/en/stable/settings.html#capture-output

Celery

http://docs.jinkan.org/docs/celery/userguide/optimizing.html https://blog.balthazar-rouberol.com/celery-best-practices http://orangleliu.info/2014/08/09/celery-best-practice/

安装 librabbitmq 提升amqp访问速度,路由长任务与短任务到不同的Queue,并配置不同的预取策略.使用msgpack来序列化消息,性能优于json.

gevent 与 MySQLdb

因为redis最够快,所以在gunicorn+gevent的服务器下使用redis C客户端绑定也没什么问题,但是MySQL就不一样了,为了让MySQLdb也能在gevent/greenlet下切换引入Douban的greenify库.

https://github.com/douban/greenify

Django 优化杂谈的更多相关文章

  1. SQLSERVER数据库死锁与优化杂谈

    死锁杂谈 当数据库死锁时,SqlServer会释放一个优先级较低的锁,让另一个事务运行:所以,即时去捕捉数据库死锁,是挺不容易的. 如果,数据库死锁比较长时间,那么死锁是可以被捕捉的. 可以用SqlS ...

  2. Java后台服务慢优化杂谈

    Java后台服务慢优化杂谈 前言 你是否遇到过这样的场景,当我们点击页面某个按钮后,页面一直loading,要等待好几分钟才出结果的画面,有时直接502或504,作为一个后台开发,看到自己开发的系统是 ...

  3. django优化和扩展(一)

    mysql优化基础 进行django产品开发或上线之前,有必要了解一下mysql的基础知识,orm太过抽象,导致很多朋友对于mysql了解得太少,而且orm不像sqlalchemy那样可以跟mysql ...

  4. Unity3d游戏场景优化杂谈(3)

    LOD(Level-of-detail)是最常用的游戏优化技术 .如果你的程序可以定制开发应用LOD的模块,当然 是很美好的事情.不过如果没有也没关系,大家可以使用UniLOD这个第三方的LOD插件. ...

  5. Android内存优化杂谈

    Android内存优化是我们性能优化工作中比较重要的一环,这里其实主要包括两方面的工作: 优化RAM,即降低运行时内存.这里的目的是防止程序发生OOM异常,以及降低程序由于内存过大被LMK机制杀死的概 ...

  6. django优化--ORM查询

    ORM提供了两个方法用来优化查询效率 1. select_related 有两张表:表结构如下: class Scheme(models.Model): """ 套餐类 ...

  7. django优化--ORM优缺点

    谈Django绕不开ORM ORM : ORM概念,ORM特点,ORM 的优点,ORM 的缺点 orm : 对象关系映射 (Object Relational Mapping) ,用于实现面向对象编程 ...

  8. Unity3d游戏场景优化杂谈(2)

    动态实时灯光相比静态灯光,非常耗费资源.所以除了能动的角色和物体(比如可以被打的到处乱飞的油桶)静态的地形和建筑,通通使用Lightmap. 强大的Unity内置了一个强大的光照图烘焙工具Beast, ...

  9. Unity3d游戏场景优化杂谈(4)

    首先介绍下draw call(这个东西越少你的游戏跑的越快): 在游戏中每一个被展示的独立的部分都被放在了一个特别的包中,我们称之为“描绘指令”(draw call),然后这个包传递到3D部分在屏幕上 ...

随机推荐

  1. c++使用map保存成员函数地址

    note 本基于c++11介绍一种使用map保存成员函数地址 可避免使用 if 和 switch 配置灵活 方便, 代码维护效率高 结果: 范例开始 头文件包含 #include <iostre ...

  2. CMake判断操作系统和编译器

    判断操作系统 IF (CMAKE_SYSTEM_NAME MATCHES "Linux") ELSEIF (CMAKE_SYSTEM_NAME MATCHES "Wind ...

  3. 【LeetCode】497. Random Point in Non-overlapping Rectangles 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/random-p ...

  4. 【剑指Offer】丑数 解题报告

    [剑指Offer]丑数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题目描述: ...

  5. 【LeetCode】228. Summary Ranges 解题报告(Python)

    [LeetCode]228. Summary Ranges 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/sum ...

  6. 教学日志:javaSE-数组

    一.一维数组 import java.util.Scanner; /* 数组:存储一组相同数据类型的有序集合. 特点: 1.数组中的元素必须是同一种数据类型,可以是基本数据类型,也可以是引用数据类型 ...

  7. 第八个知识点:交互式的定义如何帮助计算和IP类问题是什么

    第八个知识点:交互式的定义如何帮助计算和IP类问题是什么 这是系列中的第8篇,我们主要讨论计算中交互作用的用处和IP类问题是什么. 为了回答这些问题,我们首先给交互式证明系统一个简洁的介绍.众所周知, ...

  8. Vue.js高效前端开发 • 【Vue基本指令】

    全部章节 >>>> 文章目录 一.Vue模板语法 1.插值 2.表达式 3.指令概述 4.实践练习 二.Vue绑定类样式和内联样式 1.Vue绑定类样式 2.Vue绑定内联样式 ...

  9. Java基础周测试(一)详解

    一.单选题 (题数:30,共 150.0 分) 1.下列选项不可作为Java语言变量名的是(    ).(5.0分) A.a1            B.$1           C._1       ...

  10. 利用自定义动画 animate() 方法,实现某图书网站中“近 7 日畅销榜”中的图书无缝垂直向上滚动特效:当光标移入到图书上时,停止滚动,鼠标移开时,继续滚动

    查看本章节 查看作业目录 需求说明: 利用自定义动画 animate() 方法,实现某图书网站中"近 7 日畅销榜"中的图书无缝垂直向上滚动特效:当光标移入到图书上时,停止滚动,鼠 ...