#はじめに
Djangoのキャッシュ機能を使って、画面表示の高速化にトライしてみました。
今回、キャッシュを保存する先はMemcahcedとしています。
その他の保存先としてファイルや、データベースを使うこともできます。
データベースをキャッシュとする方法や、キャッシュ設定前後の処理時間の比較は、前回の記事「Djangoのキャッシュ機能を使って画面表示を高速化する データベース編」を見てください。
#この記事の構成
- Djangoの開発サーバーでMemcachedを使う方法について解説します
- MemcachedによりDjangoの動きがどのように変わったかを見てみます
ここで説明するのはあくまで開発サーバーでMemcachedを使う方法ですので、本番環境で使う場合にはsettings.pyの設定を適宜変更する必要があります。
本番環境の一例としてHeroku環境のDjangoでMemcachedを使う方法については以下を参照ください。
#環境
- macOS High Sierra 10.13.6
- Python 3.7.0
- Django 2.1
- python-memcached 1.59
#1. Djangoの開発サーバーでMemcachedを使う方法
##1.1. Memcachedをインストールする
$brew install memcached
##1.2. Memcachedを起動する
$ brew services start memcached
##1.3. python-memcachedをインストールする
pythonでmemcashedを使う為に、python-memcachedをインストールします。
(myvenv) $ pip install python-memcached
##1.4. settings.pyにキャッシュの設定を行う
settings.py
に以下を追加します。
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
BACKEND
の部分がキャッシュの保存先の種類を示していて、Memcachedを使う場合はmemcached.MemcachedCache
と指定します。
LOCATION
の部分は、Memcahcedが稼動するサーバーとポート番号を指定します。
Djangoの開発サーバーのIPアドレスが127.0.0.1
なのであれば、127.0.0.1:11211
と指定します。
11211
は、Memcachedのデフォルトのポート番号です。
##1.5. キャッシュする対象を指定する
今回はアクセスの多い特定のURLのページだけをキャッシュすることにしました。そのような場合は、urls.py
でキャッシュする対象を指定します。
もともとのurls.py
が以下のような内容だった場合・・・
from django.urls import path
from . import views
urlpatterns = [
path('', views.ArticleListView.as_view(), name='article_list'),
# 略
]
以下のようにcache_page
関数を使います。秒数の部分は60 * 15
と記述することで15分であることをわかりやすくしています。
from django.urls import path
from django.views.decorators.cache import cache_page # ここを追加
from . import views
urlpatterns = [
# cache_page(秒数)(ビュー)を追加する
path('', cache_page(60 * 15)(views.ArticleListView.as_view()), name='article_list'),
# 略
]
#2. キャッシュによりDjangoの動きがどのように変わったかを見てみる
キャッシュ設定前後で何が変わったのかをdjango-debug-toolbarの機能を使って見てみることにします。
django-debug-toolbarの設定方法は以下を参考にさせていただきました。
Djangoメモ(14) : Django Debug Toolbarでデバッグ情報を表示
##2.1. キャッシュ設定無し(Memcachedを停止)
$ brew services stop memcached
画面は自作のDjangoアプリです。
右端の黒いツールバー部分がdjango-debug-toolbarによって表示されている情報です。
「時刻」に表示されているのがCPUの処理時間だと思われます。約163ミリ秒かかっています。
なお、SQLは3本発行されてます。
ちなみに処理時間の内訳は以下のようになっています。
##2.2. キャッシュ設定あり(memcached起動中)の時の初回のアクセス
前回の記事ではキャッシュの保存先をデータベースとしましたが、その場合、初回アクセス時に関してはキャッシュテーブルへの書き込みが発生する都合上、逆に処理時間が増えてしまうという弊害がありました。
処理時間が約335ミリ秒(+154ミリ秒)に増えてしまいました。
また、SQLの発行本数も14本(+9本)に増えています。
SQLの本数が増えたのはキャッシュ用のテーブルへの読み書きを行ったためのようです。
キャッシュの有無を調べるSQL、(キャッシュが無いので)ページの情報をキャッシュへ書き込むSQLが発行されていました。
Memcachedの場合はどうなるのでしょうか?
Memcachedを起動した上で、画面にアクセスします。
$ brew services start memcached
Memcached停止中での画面アクセスと比較して、処理時間は約164ミリ秒(+1ミリ秒)とほぼ変化はありません。
また、SQLの発行本数についても3本のままで、増加はありません。
##2.3. キャッシュ設定ありの時の2回目のアクセス
処理時間が約9ミリ秒と大幅に減りました(-154ミリ秒)。
また、SQLの発行本数は0本(-3本)となりました。
まとめ
##Memcachedの場合
条件 | CPU処理時間(ms) | SQL本数 |
---|---|---|
キャッシュ設定無し | 163 | 3 |
キャッシュ設定あり・初回アクセス | 164 | 3 |
キャッシュ設定あり・2回目のアクセス | 10 | 0 |
たったの1回ずつしかアクセスしていないので厳密な検証ではありませんが、初回のアクセスにおいてもキャッシュ設定無しの時より画面表示に時間がかかってしまうようなことは無く、2回目以降のアクセスは大幅に時間が短くなることが期待できるようです。
##ちなみにデータベースの場合
同一のDjangoアプリケーションで、キャッシュの保存先をデータベースとした場合の処理時間も記載しておきます。
この結果を見ると、キャッシュの保存先はデータベースよりもMemcachedとした方が良さそうですね。
条件 | CPU処理時間(ms) | SQL本数 |
---|---|---|
キャッシュ設定無し | 163 | 3 |
キャッシュ設定あり・初回アクセス | 326 | 12 |
キャッシュ設定あり・2回目のアクセス | 22 | 2 |
#参考
- 現場で使える Django の教科書《実践編》
- Django’s cache framework(英語)
- [macでmemcachedを導入する手順]
(https://qiita.com/makotok7/items/9998b15f79fc7a53af24)