• Django 优化杂谈


    Django 优化杂谈

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

    数据库连接池

    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

  • 相关阅读:
    Android-Drawable
    DOM4J与JDOM解析xml文档
    SAX解析xml文档
    java中的xml简介与DOM解析xml
    二进制I/O
    java中的集合框架
    文本I/O
    Java中基本数据的包装类
    Sting 字符串类
    抽象类和接口
  • 原文地址:https://www.cnblogs.com/rangger/p/9801593.html
Copyright © 2020-2023  润新知