Djangoでキャッシュ機能を実装して高速化する方法|ファイルやDBでの方法を解説

スポンサーリンク

今回は、Django のキャッシュを実装します。

キャッシュとは何か、なぜキャッシュを使うのか、そして最後に、私たちの Web アプリケーションにキャッシュを実装するためのコードを書きます。

では、始めましょう!

スポンサーリンク

キャッシュとは

キャッシュとは、時間のかかる計算結果を保存しておき、次回以降、必要なときにすぐに計算結果を得られるようにすることです。

コンピュータのCPUでも、キャッシュファイルをメモリに保存しておき、次回にそのファイルを高速に表示できるようにして、処理時間を大幅に短縮しています。

FBやWhatsAppのようなウェブサイトの多くも、ウェブサイトの速度を向上させるためにキャッシュを使用しています。

Django Framework には、Web サイトをキャッシュするために使用できる、あらかじめ組み込まれたオプションのセットがあります。

キャッシュの必要性

動的なウェブサイト(テンプレート、ビュー、サーバー内のデータなど動的な要素を含むウェブサイト)を閲覧するたびに、サーバーはテンプレート、ビューを読み込み、サーバーからデータを取得して表示する必要があります。

このすべての処理に時間が必要です。

しかし、今の時代、どのユーザーも自分のリクエストに素早く応えてほしいと思っており、ミリ秒の遅れも許されない。

そこで、Webサイトを高速化するために、以下のいずれかの方法をとります。

  • CPUハードウェアの改善
  • サーバーソフトウェアの改善
  • データベースの改善

または、単純にキャッシュという方法を使うか!?

キャッシュ情報の保存

Django のキャッシュフレームワークは、キャッシュ情報を保存するための様々な 方法も提供しています。

  • DB にキャッシュを格納する
  • キャッシュをファイルに保存する
  • キャッシュをメモリに保存する

では、それぞれを個別に見ていきましょう

1)キャッシュをDBに格納します。

ここでは、全てのキャッシュデータは、モデルテーブルと同じように、データベース内の別のテーブルに格納されています。

従って、キャッシュを DB に保存するよう Django に指示する必要があります。

これを行うには、 settings.py に以下のコードを追加します。

CACHES = {
    'default':{
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
    }
}

キャッシュをテーブルに格納するために、テーブルを作成する必要があります。

python manage.py createcachetable

Django は、settings.py で指定された名前 “my_cache_table” で DB 内にキャッシュテーブルを作成します。

この方法は最もよく使われる方法ですが、キャッシュの速度は DB のタイプに依存します。

高速なDBを使用している場合、このオプションが最も有効です。

2) キャッシュをファイルに保存する

ここでは、キャッシュをファイルとしてシステムに保存します。

キャッシュをファイルに保存するには、settings.py に次のコードを追加します。

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': 'Absolute_path_to_the_directory',
    }
}

ここでは、すべてのキャッシュファイルは、LOCATION属性で設定されたフォルダ/ディレクトリに保存されます。

注意

  • サーバーはそのディレクトリにアクセスできる必要があります。
  • LOCATIONは事前に存在している必要があります。
  • フォルダ/ディレクトリの絶対パスだけを記載します。

この方法は、すべてのオプションの中で最も遅いです。

しかし、ここでは、システム内の既存のストレージを使用しているため、ハードウェアをアップグレードする必要はありません。

3)キャッシュをメモリに格納する

ここでは、全てのキャッシュファイルをメモリに保存します。

Django には、インローカルメモリキャッシュという形で、デフォルトのキャッシングシステムがあります。

ローカルメモリにキャッシュを追加するには、以下のコードを追加します。

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': ('Location1','Location2',...),
    }
}

ここでは、キャッシュファイルを異なる部分に分けて保存することができます。

LOCATION 属性にすべての部分の位置をタプルとして追加します。

この方法は、上記のすべてのオプションの中で、圧倒的に強力かつ高速な方法です。

Django キャッシングのための前提条件

さて、ウェブサイトをキャッシュするためには、まずビューとそれに対応する URL パスが必要です。

そこで、以下のサンプルの View を views.py に追加してください。

def SampleView(request):
    Html = '<h1>Django Caching<h1><br><p>Welcome to Caching Tutorial</p>'
    return HttpResponse(html)

このコードの URL パスは次のようになります。

path('sample/', SampleView),

次に、キャッシュの保存方法ですが、上記のような形で保存します。

ウェブサイトのさまざまな部分をキャッシュとして保存する

Django では、次のようなことができます。

  1. 特定のビューだけをキャッシュする
  2. または Web サイト全体をキャッシュする

これから、これらを個別に見ていきます。

1. サイト単位のキャッシュ保存

サイト全体をキャッシュするには、settings.pyのMIDDLEWAREセクションに次のコードを追加します。

'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',

Note: 上記のコードの順番は重要です。

同じ順番で存在することを確認してください。

サイト単位のストレージキャッシュの実装

サーバーを起動し、URLパス “/sample” にアクセスします。

#Method1: Cach_page syntax in views.py
from django.views.decorators.cache import cache_page
 
@cache_page(200)
def SampleView(request):
    html = '<h1>Django Caching<h1><br><p>Welcome to Caching Tutorial</p>'
    return HttpResponse(html)
 
#Method2: Cache_page syntax in urls.py
from django.views.decorators.cache import cache_page
urlpatterns = [
    path('sample/', cache_page(200)SampleView),
]

サイトの初回読み込みに13msかかっていることに注目してください。

ここでリロードを押して、もう一度確認してください。

Per-Site Cache 1
Per-Site Cache

今度は、ページの再読み込みにわずか6msを要したことに注目してください。

時間は半分以下に短縮されました。

2. ビュー単位のキャッシュストレージ

特定のViewだけをキャッシュする場合、以下のような構文になります。

Per-Site Cache 2
Per-Site Cache 2

cache_page() 属性は、1つの引数 – キャッシュの有効期限(秒)を取るだけです。

上記の2つのメソッドのいずれかを使用できます。

ビュー単位のストレージキャッシュの実装

サーバーを起動し、URLを叩く

Per-View Cache 1
Per-View

所要時間は22msです。

再読み込みして確認します。

Per-View Cache 2
Per-View Cache 2

所要時間は8msに短縮されました。

まとめ

以上です。

キャッシュについて、そしてウェブアプリケーションのニーズと要件に応じたキャッシュの使用方法について、良い知識を得ることができたと思います。

このトピックの理解を深めるために、上に挙げたすべてのコードを実践してみてください。

タイトルとURLをコピーしました