- 更新
2013-10-23
- バージョン
0.1.2
- 作者
@voluntas
- URL
- Python
2.7.5
- MySQL
5.6.14
- redis
2.6.16
C 拡張 API を使っている MySQL-Python は gevent のパッチが当てられないため使えないので PyMySQL を使用する
- Django + Gunicorn + Gevent 使えるようにする
- Django で MySQL-Python を使わず PyMySQL を使う
- 全てを非同期で実行出来るように gevent のパッチを当てる
- Celery の処理を Gevent を使って非同期にする
- gunicorn + meinheld を使う
- Redis との連携
gevent と PyMySQL は Git リポジトリから開発版をインストールする
celery / django-celery は後ほど登場します
$ pip install -r requirements.txt
requirements.txt:
Cython==0.19.1
Django==1.5.4
-e git+https://github.com/PyMySQL/PyMySQL.git#egg=PyMySQL
-e git+https://github.com/surfly/gevent.git#egg=gevent
-e git+https://github.com/mopemope/meinheld.git#egg=meinheld
gunicorn==18.0
uWSGI==1.9.18.1
redis==2.8.0
celery==3.0.23
django-celery==3.0.23
snowflake は仮のアプリ名なので置き換える事
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "snowflake.settings")
from gevent import monkey
monkey.patch_all()
import pymysql
pymysql.install_as_MySQLdb()
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'snowflake',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
INSTALLED_APPS = (
...
# 追加
'gunicorn',
...
)
MySQL-python は未インストール
$ python manage.py syncdb
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table django_site
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): no
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
$ python manage.py run_gunicorn -w 1 -k gevent --worker-connections=4096 --backlog=1000
2013-09-22 13:35:14 [43326] [INFO] Starting gunicorn 18.0
2013-09-22 13:35:14 [43326] [INFO] Listening at: http://127.0.0.1:8000 (43326)
2013-09-22 13:35:14 [43326] [INFO] Using worker: gevent
2013-09-22 13:35:14 [43329] [INFO] Booting worker with pid: 43329
まだ未完成
$ uwsgi --gevent 100 --socket :3031 --module myapp
まだ未完成
$ python manage.py run_gunicorn -w 2 --worker-connections=4096 --backlog=1000 --worker-class="egg:meinheld#gunicorn_worker"
2013-10-22 11:22:45 [22724] [INFO] Starting gunicorn 18.0
2013-10-22 11:22:45 [22724] [INFO] Listening at: http://127.0.0.1:8000 (22724)
2013-10-22 11:22:45 [22724] [INFO] Using worker: egg:meinheld#gunicorn_worker
2013-10-22 11:22:45 [22727] [INFO] Booting worker with pid: 22727
2013-10-22 11:22:45 [22728] [INFO] Booting worker with pid: 22728
2013-10-22 11:22:45 [22729] [INFO] Booting worker with pid: 22729
2013-10-22 11:22:45 [22730] [INFO] Booting worker with pid: 22730
broker には簡単に使えて安定している redis を使う
高負荷対策で使う場合は RabbitMQ を検討すると良い
redis のダウンロードから動作までは以下を参照
https://gist.github.com/voluntas/21759d5c45aacc0e6656#redis
非同期タスクキューへの接続も Gevent を使ってみる
settings.py に Celery の設定を追加する
INSTALLED_APPS = (
...
'gunicorn',
# 追加
'djcelery',
...
)
# celery
import djcelery
djcelery.setup_loader()
BROKER_URL = 'redis://127.0.0.1:6379/4'
- -Q は --queues
- -P は --pool
- -c は --concurrency
$ python manage.py celery worker -Q celery_gevent -P gevent -c 1024
-------------- celery@192.0.2.1 v3.0.23 (Chiastic Slide)
---- **** -----
--- * *** * -- Darwin-12.5.0-x86_64-i386-64bit
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> broker: redis://127.0.0.1:6379/4
- ** ---------- .> app: default:0x10ea3d510 (djcelery.loaders.DjangoLoader)
- ** ---------- .> concurrency: 1024 (gevent)
- *** --- * --- .> events: OFF (enable -E to monitor this worker)
-- ******* ----
--- ***** ----- [queues]
-------------- .> celery_gevent: exchange:celery_gevent(direct) binding:celery_gevent