Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
Djangoアプリケーション 
パフォーマンスチューニング 
@hirokiky
話すこと 
Djangoアプリケーション高速化 
パフォーマンス測定ツール
話さないこと 
ミドルウェアパラメータ調整 
検証用データの作成方法 
なんか魔法みたいに速くなる技
自己紹介 
@hirokiky 
Python Django 好き 
ギョームで100万ユーザーくらいのサイト 
Django本体への貢献
Github 
https://github.com/hirokiky/
Djangoアプリ高速化 
SQLを吐きまくるコードは誰だ 
インデックス 
キャッシュキャッシュキャッシュ 
アプリケーション外
SQLを吐きまくるコードは誰だ 
● django-debug-toolbar 
dbログ出力
django-debug-toolbar 
デモ 
https://pypi.python.org/pypi/django-debug-toolbar
django-debug-toolbar
dbログ出力
dbログ出力設定例 
LOGGING['loggers']['django.db.backends'] = { 
'level': 'DEBUG', 
'handlers': ['console'] 
} 
'console'ハンドラーは標準出...
SQLを吐きまくるコードを倒す 
● .select_related/.prefetch_related 
.bulk_create / .update 
.count / .exists
.select_related (demo) 
● FK先のデータも一緒に取ってくる 
内部的にはJOINなどが走る
.prefetch_related (demo) 
● FK元のデータも一緒に取ってくる 
複数クエリを実行しPython側で結合
.bulk_create (demo) 
● 複数のオブジェクトを一度に作成
.update
.exist - countダメ
その他 
● .only / .defer 
.values / .values_list 
アプリケーションが複雑化しやすい....
QuerySetはlazy 
>>> articles = Article.objects.all() 
>>> articles = articles.filter(title__startswith='title') 
>>> print(...
ここまでのまとめ 
● ORMが実行するSQLを知ろう 
ORMの特性を意識しよう 
他にも: https://docs.djangoproject.com/en/1.7/topics/db/optimization/
インデックス 
● 適切なインデックスを使おう 
結局相手にしてるのはRDB
インデックス 
1) 吐かれてるSQLをみて適応してく 
2) インデックスがかかるクエリに変更
吐かれるクエリは? 
検証環境などにデータたっぷりいれて 
画面をポチポチします 
JetProfilerなどがツールも優秀です
JetProfiler for MySQL 
http://www.jetprofiler.com/tour/
インデックスの貼り方 
ここでは話しません
インデックスがかかるクエリにする 
.extra: クエリの一部分を生SQLで書く 
.raw: クエリを生SQLで書く 
複雑化しやすいのでキャッシュとの兼ね合いです
ここまでのまとめ 
● クエリを眺めてインデックス適応 
好みのクエリを走るようにする 
あとそもそもテーブルの設計ちゃんとしましょう
キャッシュキャッシュキャッシュ 
キャッシュの種類と使いどころ 
Redisでのキャッシュ
キャッシュの種類 
レスポンスキャッシュ 
ビューキャッシュ 
テンプレートキャッシュ 
オブジェクトキャッシュ 
効果的 
https://docs.djangoproject.com/en/1.7/topics/cache/
テンプレートキャッシュ 
{% load cache %} 
{% cache 500 sidebar %} 
.. sidebar .. 
{% endcache %} 
https://docs.djangoproject.com/en/1...
キャッシュの使いどころ 
ユーザーに依存する表示は基本キャッシュ無理 
画面設計段階でどこキャッシュできるか考える
Redisでキャッシュ 
Redisならではの型を有効利用: 
* Set型でユニークユーザーの管理 
* SortedSet型でランキング 
http://redis.io/
まとめ 
ユーザーに近いほどキャッシュは有効 
あまり複雑化しないように設計
アプリケーション外 
セッションバックエンド変更 
静的ファイル圧縮 
DBのPrimary/Replica構成
セッションバックエンド変更 
Cacheバックエンド 
Redisのバックエンド
Redisバックエンド 
$ pip install django-redis-sessions 
SESSION_ENGINE = 'redis_sessions.session' 
https://pypi.python.org/pypi/...
静的ファイル圧縮 
django-compressor か django-asset
django-compressor 
{% load compress %} 
{% compress css %} 
<link rel="stylesheet" href="/static/css/one.css" type="text/c...
DBのMaster/Slave 
django-replicatedが便利 
レプリ遅延にも賢く対応
django-replicated 
$ pip install django-replicated 
DATABASES = {'default': {...}, 
'slave1': {...}} 
DATABASE_SLAVES = ['...
レプリ遅延対策 
MIDDLEWARE_CLASSES = [ 
... 
'django_replicated.middleware.ReplicationMiddleware', 
] 
GET, HEADで slave, それ以外で ma...
レプリ遅延対策 2 
from django_replicated.decorators import use_master, use_slave 
@use_master 
def my_view(request, ...): 
# GETで...
まとめ 
ORMの使い方は基本としてマスター 
インデックス+キャッシュのバランス 
まんべんなくやっとくのが吉です
Funkloadでパフォーマンス測定 
負荷試験ツール (Pythonで書く) 
セッション付きのシナリオ 
静的ファイルの自動取得などリッチ 
https://funkload.nuxeo.org/
Funkload (テストシナリオ) 
1) 一覧画面 
2) 詳細画面 
3) 編集画面 
4) 更新 
5) 詳細画面
Funkload (demo) 
$ fl-run-test test_Wiki.py 
$ fl-run-bench test_Wiki TestWiki.test_update
Funkload 一覧画面
Funkload 詳細画面
Funkload 編集画面
Funkload 更新
Funkload 詳細画面
Funkload レポートビルド 
$ fl-run-test test_Wiki.py 
$ fl-run-bench test_Wiki TestWiki.test_update
レポートその他 
2レポート間の差分レポート 
複数レポートでのトレンドレポート
耐えるべき負荷は? 
アクティブユーザー10万人、1日100万PV 
ピーク時でその3倍として秒間34PV 
人間1人5秒/1ページとして同時接続数170 
このあたり模索中で良い方法などあれば教えてください
ここまでのまとめ 
FunkloadはPythonで書ける 
シナリオでかけるので信頼できる
全体まとめ 
ORMの扱いなどは当たり前にやっておく 
面倒、複雑なものは測定しつつ必要な分やる
感想 
カッコいいこと言っても結局 
設計とミドルウェアが重要 
どううまく使うかを考えましょう
出会い系 
オフィスアワー(会議室4/5)に13:15〜 
Sprint(3日目)
@hirokiky
Nächste SlideShare
Wird geladen in …5
×

Pycon2014 django performance

Djangoアプリケーションチューニング、Djangoアプリケーションのチューニング方法、負荷測定方法を紹介します。PyConJP2014での発表資料です。
発表の動画はこちら http://youtu.be/1aLAZG4Udg0

Pycon2014 django performance

  1. 1. Djangoアプリケーション パフォーマンスチューニング @hirokiky
  2. 2. 話すこと Djangoアプリケーション高速化 パフォーマンス測定ツール
  3. 3. 話さないこと ミドルウェアパラメータ調整 検証用データの作成方法 なんか魔法みたいに速くなる技
  4. 4. 自己紹介 @hirokiky Python Django 好き ギョームで100万ユーザーくらいのサイト Django本体への貢献
  5. 5. Github https://github.com/hirokiky/
  6. 6. Djangoアプリ高速化 SQLを吐きまくるコードは誰だ インデックス キャッシュキャッシュキャッシュ アプリケーション外
  7. 7. SQLを吐きまくるコードは誰だ ● django-debug-toolbar dbログ出力
  8. 8. django-debug-toolbar デモ https://pypi.python.org/pypi/django-debug-toolbar
  9. 9. django-debug-toolbar
  10. 10. dbログ出力
  11. 11. dbログ出力設定例 LOGGING['loggers']['django.db.backends'] = { 'level': 'DEBUG', 'handlers': ['console'] } 'console'ハンドラーは標準出力に表示する想定
  12. 12. SQLを吐きまくるコードを倒す ● .select_related/.prefetch_related .bulk_create / .update .count / .exists
  13. 13. .select_related (demo) ● FK先のデータも一緒に取ってくる 内部的にはJOINなどが走る
  14. 14. .prefetch_related (demo) ● FK元のデータも一緒に取ってくる 複数クエリを実行しPython側で結合
  15. 15. .bulk_create (demo) ● 複数のオブジェクトを一度に作成
  16. 16. .update
  17. 17. .exist - countダメ
  18. 18. その他 ● .only / .defer .values / .values_list アプリケーションが複雑化しやすい....
  19. 19. QuerySetはlazy >>> articles = Article.objects.all() >>> articles = articles.filter(title__startswith='title') >>> print(articles) >>> >>> q = articles.filter(author_id=1) >>> print(q) ここでクエリ実行 https://docs.djangoproject.com/en/1.7/topics/db/queries/#querysets-are-lazy
  20. 20. ここまでのまとめ ● ORMが実行するSQLを知ろう ORMの特性を意識しよう 他にも: https://docs.djangoproject.com/en/1.7/topics/db/optimization/
  21. 21. インデックス ● 適切なインデックスを使おう 結局相手にしてるのはRDB
  22. 22. インデックス 1) 吐かれてるSQLをみて適応してく 2) インデックスがかかるクエリに変更
  23. 23. 吐かれるクエリは? 検証環境などにデータたっぷりいれて 画面をポチポチします JetProfilerなどがツールも優秀です
  24. 24. JetProfiler for MySQL http://www.jetprofiler.com/tour/
  25. 25. インデックスの貼り方 ここでは話しません
  26. 26. インデックスがかかるクエリにする .extra: クエリの一部分を生SQLで書く .raw: クエリを生SQLで書く 複雑化しやすいのでキャッシュとの兼ね合いです
  27. 27. ここまでのまとめ ● クエリを眺めてインデックス適応 好みのクエリを走るようにする あとそもそもテーブルの設計ちゃんとしましょう
  28. 28. キャッシュキャッシュキャッシュ キャッシュの種類と使いどころ Redisでのキャッシュ
  29. 29. キャッシュの種類 レスポンスキャッシュ ビューキャッシュ テンプレートキャッシュ オブジェクトキャッシュ 効果的 https://docs.djangoproject.com/en/1.7/topics/cache/
  30. 30. テンプレートキャッシュ {% load cache %} {% cache 500 sidebar %} .. sidebar .. {% endcache %} https://docs.djangoproject.com/en/1.7/topics/cache/
  31. 31. キャッシュの使いどころ ユーザーに依存する表示は基本キャッシュ無理 画面設計段階でどこキャッシュできるか考える
  32. 32. Redisでキャッシュ Redisならではの型を有効利用: * Set型でユニークユーザーの管理 * SortedSet型でランキング http://redis.io/
  33. 33. まとめ ユーザーに近いほどキャッシュは有効 あまり複雑化しないように設計
  34. 34. アプリケーション外 セッションバックエンド変更 静的ファイル圧縮 DBのPrimary/Replica構成
  35. 35. セッションバックエンド変更 Cacheバックエンド Redisのバックエンド
  36. 36. Redisバックエンド $ pip install django-redis-sessions SESSION_ENGINE = 'redis_sessions.session' https://pypi.python.org/pypi/django-redis-sessions
  37. 37. 静的ファイル圧縮 django-compressor か django-asset
  38. 38. django-compressor {% load compress %} {% compress css %} <link rel="stylesheet" href="/static/css/one.css" type="text/css"> <style type="text/css">p { border:5px solid green;}</style> <link rel="stylesheet" href="/static/css/two.css" type="text/css"> {% endcompress %} http://django-compressor.readthedocs.org/en/latest/
  39. 39. DBのMaster/Slave django-replicatedが便利 レプリ遅延にも賢く対応
  40. 40. django-replicated $ pip install django-replicated DATABASES = {'default': {...}, 'slave1': {...}} DATABASE_SLAVES = ['slave1'] DATABASE_ROUTERS = ['django_replicated.ReplicationRouter'] 更新が master, 参照が slave になります https://github.com/yandex/django_replicated
  41. 41. レプリ遅延対策 MIDDLEWARE_CLASSES = [ ... 'django_replicated.middleware.ReplicationMiddleware', ] GET, HEADで slave, それ以外で master https://github.com/yandex/django_replicated
  42. 42. レプリ遅延対策 2 from django_replicated.decorators import use_master, use_slave @use_master def my_view(request, ...): # GETで更新&参照するViewなんだぜ。。。 Viewに強制指定 https://github.com/yandex/django_replicated
  43. 43. まとめ ORMの使い方は基本としてマスター インデックス+キャッシュのバランス まんべんなくやっとくのが吉です
  44. 44. Funkloadでパフォーマンス測定 負荷試験ツール (Pythonで書く) セッション付きのシナリオ 静的ファイルの自動取得などリッチ https://funkload.nuxeo.org/
  45. 45. Funkload (テストシナリオ) 1) 一覧画面 2) 詳細画面 3) 編集画面 4) 更新 5) 詳細画面
  46. 46. Funkload (demo) $ fl-run-test test_Wiki.py $ fl-run-bench test_Wiki TestWiki.test_update
  47. 47. Funkload 一覧画面
  48. 48. Funkload 詳細画面
  49. 49. Funkload 編集画面
  50. 50. Funkload 更新
  51. 51. Funkload 詳細画面
  52. 52. Funkload レポートビルド $ fl-run-test test_Wiki.py $ fl-run-bench test_Wiki TestWiki.test_update
  53. 53. レポートその他 2レポート間の差分レポート 複数レポートでのトレンドレポート
  54. 54. 耐えるべき負荷は? アクティブユーザー10万人、1日100万PV ピーク時でその3倍として秒間34PV 人間1人5秒/1ページとして同時接続数170 このあたり模索中で良い方法などあれば教えてください
  55. 55. ここまでのまとめ FunkloadはPythonで書ける シナリオでかけるので信頼できる
  56. 56. 全体まとめ ORMの扱いなどは当たり前にやっておく 面倒、複雑なものは測定しつつ必要な分やる
  57. 57. 感想 カッコいいこと言っても結局 設計とミドルウェアが重要 どううまく使うかを考えましょう
  58. 58. 出会い系 オフィスアワー(会議室4/5)に13:15〜 Sprint(3日目)
  59. 59. @hirokiky

×