キャッシング - Djangoのキャッシュフレームワーク
動的なWebサイトの基本機能は、はい、それは動的である、ということです。たびに、ユーザーがページを要求すると、Webサーバー、計算が完全に実施する必要があります - ページまで最終的なショーを作成 - ビジネスロジックデータベースがレンダリングするためにクエリから。ビューのサーバーの観点から負荷は、これまでのところだけで、ファイルシステムからファイルを読み込むに占有される多くのシステムリソースを示しています。
gbvy[W
Webアプリケーションの大半は、このような負荷が大きな問題ではない。 Webアプリケーションのほとんどは、washingtonpost.comや忙しいslashdot.orgとされていない、彼らは通常、小さい - サイズではなく、特にクリック率の高い媒体。しかし、大規模サイト上で高いクリック率は、WEBサーバの負荷を低減することができる必要があります。
キャッシュメカニズムの目的は、計算の手順(再度アクセス)に省略されている適切な時間を確立する。メカニズムはどのように動作するか、次の擬似コードは説明する:
ページに戻る
それ以外の場合:
[ビルド]ページ
生成されると、このページに戻る
Djangoでは、動的なページを保存することができます実用的かつ効率的なキャッシュシステムが付属していますので、すべての要求を計算する必要はない、新しいページを生成します。利便性を使用するためには、Djangoはキャッシュモードの異なるレベルを提供しています:あなたは、あなたがキャッシュは、サイト全体ができますご希望の場合は、指定されたビューのキャッシュのみの出力は、あなただけの、高いのキャッシュフラグメントの量を計算することができますすることができます。
Djangoと"上流の"キャッシュはキャッシュのようにイカ(とブラウザベースの、非常に良いコラボレーションすることができます。これらのキャッシュモードでは、することができますが直接制御が指示するヘッダのHTTPれるかもしれないサイトの部品をキャッシュする方法キャッシュを消去します。
セットキャッシュ
設定を設定することにより設定されているキャッシュタイプCACHE_BACKENDにを決定するためにファイルです。オプションのすべての可能な値は次の詳細:
Memcached
インストールされてMemcachedのは、memcachedのPythonバインディングをインストールする必要があります。これは、別のPythonモジュールは、memcache.py、あなたが得ることができるです。 URLは、そのPythonバインディングで(そして"クライアントAPI"を介して部分的には、Memcachedを直接Webサイトにアクセスできない場合。
/ / IPアドレス::ポート/ ipはmemcachedデーモンのIPアドレス、ポートは、memcachedのプロセスによって使用されるポートですDjangoのMemcachedは使用するには、memcachedをしてCACHE_BACKENDに設定してください。
次の例では、memcachedは11211ポートのローカルホスト(127.0.0.1)で実行されている:
CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11211/'
メモリ内のデータをキャッシュするため、サーバーが低速のデータが失われますクラッシュ:メモリベースのキャッシュには1つの欠点を持っています。誰もがあなたがデータを保持する唯一の方法は、メモリベースのキャッシュに依存すべきではない、メモリが完全にデータを格納するためには適していないことを知っている。実際には、永久保存のためのDjangoのキャッシュバックエンドデータなし - が存在する理由は、キャッシュするには、この目的とするものであるが恒久的に格納されているデータ - 私たちはこれをキャッシュのメモリ不足のためです指すためにここにいる他の一時的なより方法です。
データベースキャッシュ
最初に、データベースキャッシュのバックエンドを使用して、キャッシュテーブル内のデータベースを作成しますか?次のコマンドを実行します:
python manage.py createcachetable [cache_table_name]
...ここでは[cache_table_name]は、テーブルの名前で作成するデータベースのキャッシュです。 (あなたは、そうではない任意の名前を取ることができますし、テーブルの行上に同じ名前を持っている)。このコマンドは、適切なキャッシュテーブルを作成し、データベース構造を作成し、Djangoはその後、データをキャッシュするために使用します。
CACHE_BACKEND = 'db://my_cache_table'
いつまで、高速を持っているように、よくデータベースサーバーをインデックスとして、データベースキャッシュは、優れた操作です。
CACHE_BACKEND = 'file:///var/tmp/django_cache'
注:ファイル:二の代わりに3つのスラッシュが続きます。最初の二つはファイルです:/ /プロトコル、および3番目の/最初の文字をdjango_cacheは/ var / tmpのパスです。
されていること、それが実行を開始するファイルシステムのルートからする必要があります - ディレクトリパスは絶対パスでなければなりません。パスは、最後のスラッシュを追加する場合、Djangoは気にしません。
パスのセットが存在し、Webサーバーが読み書きできるようにしてください。上記の例を続行するには、サーバーがディレクトリにapacheユーザを/ var / django_cacheが存在し、ユーザーのapacheで読み取ることができますを/ tmpとして実行するようにします。
あなたは、高性能なメモリキャッシュをがしたい場合は、条件付きMemcachedを実行して、仮想ローカルメモリキャッシュのバックエンドを使用することを検討することができます。このキャッシュバックは、マルチプロセスとスレッドセーフです。それを使用するには、CACHE_BACKENDに設定"locmem:/ / /"例:
CACHE_BACKEND = 'locmem:///'
"シンプル:///"は、単純な、単一のプロセスのメモリキャッシュのタイプです。これは、プロセスだけでは、開発またはテスト環境に適用されることを意味キャッシュデータを保存するのです。例:
CACHE_BACKEND = 'simple:///'
仮想キャッシュ(開発用)
最後に、Djangoはまた、"ダミーの"キャッシュ(事実をキャッシュではなく)をサポートしています - だけではなく、キャッシュのインターフェイスを実装する実際には何もしませんでした。
This is useful if you have a production site that uses heavy-duty caching in various places but a development/test environment on which you don't want to cache. In that case, set CACHE_BACKEND to "dummy:///" in the settings file for your development environment. As a result, your development environment won't use caching and your production environment still will.
CACHE_BACKENDにパラメータ
すべてのキャッシュタイプは、パラメータを受け付けています。方法は、クエリ文字列パラメータのスタイルに似て提供する。すべての有効なパラメータのリストは次のとおりです:
timeout
max_entries
cull_percentage
あなたがキャッシュ内のエントリの最大数に達すると、エントリの選択比を維持するとき。実際= 3は、エントリの1 / 3の選択を1/cull_percentageので、設定cull_percentageが保存されますが保存され、エントリの残りの部分は削除されました。
cull_percentageは、キャッシュへのエントリの最大数が削除されていること0に設定されている場合が全体のキャッシュを消去します。キャッシュヒット率が非常に低いときに、これが大幅に(選択しないでください。)は、選択されたキャッシュエントリの効率を向上させる
この例では、タイムアウトは60に設定されています:
CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=60"
CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=30&max_entries=400"
不正なパラメータは無視されます。
キャッシュサイト全体
キャッシュタイプを設定すると、最も簡単な方法は、キャッシュのキャッシュにサイト全体を使用することです。 ``でMIDDLEWARE_CLASSES ``はdjango.middleware.cache.CacheMiddlewareは、次の例と同じに追加して設定:
MIDDLEWARE_CLASSES = (
"django.middleware.cache.CacheMiddleware",
"django.middleware.common.CommonMiddleware",
)
(MIDDLEWARE_CLASSESシーケンス依存しています。"MIDDLEWARE_CLASSESの順序"に以下を参照してください)
次に、Djangoの設定ファイルでは、以下の設定を追加:
キャッシュはキャッシュしないミドルウェアは、ページごとに/ POSTパラメータを取得している。また、CacheMiddlewareは自動的に各のHttpResponseのヘッダのいくつかの設定:
キャッシュされていないページを要求すると、現在の日付と時刻をLast - Modifiedヘッダを設定します。
セット現在の日付と時刻CACHE_MIDDLEWARE_SECONDSの定義としてExpiresヘッダがありません。
より多くの情報を知っているミドルウェアのドキュメントをミドルウェアを参照してください。
単一のビューのキャッシュ
Djangoは特定のページのみをキャッシュすることができます。 Django.views.decorators.cacheのcache_page、それが自動的にキャッシュは、応答のビューすることができます修飾子を定義しています。修飾子の使用は非常に単純です:
from django.views.decorators.cache import cache_page
def slashdot_this(request):
...
slashdot_this = cache_page(slashdot_this, 60 * 15)
または、修飾Python 2.4の構文を使用します:
@cache_page(60 * 15)
def slashdot_this(request):
...
cache_pageは1つだけのパラメータを受け付けます:キャッシュを秒単位で有効です。上記の例では、slashdot_this()はビューは15分間キャッシュされます。
キャッシュAPIは簡単です。 Django.core.cacheが自動的にセットCACHE_BACKENDに、キャッシュオブジェクトを生成するキャッシュモジュールから派生:
>>> from django.core.cache import cache
基本的なインターフェイスは、(キー、値、timeout_seconds)設定されているとget(キー):
>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'
パラメータは省略可能ですtimeout_seconds、そのデフォルト値がタイムアウトパラメータCACHE_BACKENDにと同じです。
>>> cache.get('some_other_key')
None
# Wait 30 seconds for 'my_key' to expire...
>>> cache.get('my_key')
None
デフォルトのパラメータを受け入れることができる()を取得:
>>> cache.get('my_key', 'has expired')
'has expired'
もちろん、それは一度だけキャッシュにヒット、get_many()インターフェイスがあります。 Get_many()を使用する要求のすべてのキーを期限が切れの実際の存在を含め、辞書を返します。:
>>> cache.set('a', 1)
>>> cache.set('b', 2)
>>> cache.set('c', 3)
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}
最後に、明示的にキーを削除するには、delete()を使用することができます。これは、簡単な方法をオフにしてキャッシュ内の特定のオブジェクトです:
>>> cache.delete('a')
それは。非常にキャッシュメカニズムは、いくつかの制限:することができます安全にキャッシュ(文字列でなければなりませんキー)漬けすることができる任意のオブジェクトを返します。
Upstream caches
今まで、私たちの目は、独自のデータに焦点を当てる。 "上流の"キャッシュ:WEB開発では、キャッシュの別のタイプがあります。これは、ユーザーの要求は、ブラウザのキャッシュによって実装されるサイトで到着していないです。
*あなたのDjango Webサイトは、Squid(Webプロキシサーバーに基づいてかもしれないが、それはキャッシュがページの順序でパフォーマンスを向上させるため、この場合には、各要求は、Squidによって処理される、あなたはそれがあなたに要求をアプリケーションに渡します必要がある場合のみです。
*お使いのブラウザがキャッシュされますいくつかのページ。 WEBページは、正しいヘッダを送信する場合は、ブラウザが同じページに行われた要求に応答してポストのローカル(キャッシュ)のコピーを使用します。
上流のキャッシュは非常に効果的な前進ですが、それもかなりの欠点があります:多くのWebページや権限に基づいて変数の束を、このキャッシュシステムは、やみくもにユーザーが機密情報の不適切な情報開示があるかもしれませんキャッシュされたページのURLのみに依存しています。
幸いなことに、HTTPにはこうした問題に対するソリューションを提供します:キャッシュのキャッシュメカニズムを構築するために使用されるHTTPヘッダーのシリーズは、キャッシュシステムの内容をキャッシュしないように、この特定のページを区別する。
使用ヴァリヘッダー
ヘッダーの1つはVaryです。これは、キャッシュ要求ヘッダーを作成するキーのキャッシュメカニズムを定義しています。たとえば、ページの内容は、ユーザーの言語設定に依存している場合、ページは"言語によって異なります。"と言われた
デフォルトでは、Djangoのキャッシュシステムはキャッシュキーを作成するリクエストパスを使用して - たとえば、"/ stories/2005/jun/23/bank_robbed /"です。これは、各要求のURLは、ユーザーエージェント別に関係なく、同じキャッシュされたバージョンを使用することを意味します。 (クッキーと言語機能)。
したがって、我々はヴァリする必要があります。
from django.views.decorators.vary import vary_on_headers
# Python 2.3 syntax.
def my_view(request):
...
my_view = vary_on_headers(my_view, 'User-Agent')
# Python 2.4 decorator syntax.
@vary_on_headers('User-Agent')
def my_view(request):
...
このキャッシュシステム(Djangoの独自のキャッシュミドルウェアなど)を別のユーザーエージェントがキャッシュされます異なるバージョンのページ。
変更せず修飾子を使用する利点は:修飾子は、それを上書きではなく、Varyヘッダ(既に存在する場合があります)に追加されます(Varyヘッダ手動での設定と比較して['ヴァリ'] ='user - agentの'同様の応答を使用します)。
また、変更せず()への複数のヘッダを渡すことができます:
@vary_on_headers('User-Agent', 'Cookie')
def my_view(request):
...
@vary_on_cookie
def my_view(request):
...
@vary_on_headers('Cookie')
def my_view(request):
...
変更せずに渡されるパラメータは、大文字と小文字が区別されていないことに注意してください。の"User - Agent"と"ユーザエージェント"と同じです。
また、django.utils.cache.patch_vary_headersをヘルパー関数を使用することができます:
from django.utils.cache import patch_vary_headers
def my_view(request):
...
response = render_to_response('template_name', context)
patch_vary_headers(response, ['Cookie'])
return response
patch_vary_headersは、その最初の引数は、ヘッダ名のリストまたはタプル番目のパラメータとしてのHttpResponseインスタンスを受け入れます。
ヴァリのヘッダーは公式のVary仕様を参照してください、より多くの情報を知っています。
コントロールキャッシュ:その他のヘッダーを使用して
ソリューションは、ページのキャッシュは、宣言することです"プライベート"。 Djangoでは、cache_controlビュー修飾子を使用しています。例:
from django.views.decorators.cache import cache_control
@cache_control(private=True)
def my_view(request):
...
この修飾子は、適切なHTTPヘッダを送信し、バックグラウンドで慎重にされる、上記の問題を回避するために送信されます。
キャッシュパラメータを制御するために、他の方法があります。たとえば、HTTPアプリケーションは、次のことを行うことができます:
*キャッシュにのみ送信するようにキャッシュされたバージョンを変更しない場合は、新しいバージョンの確認は常にかどうかを指定します。 (変更がキャッシュされたバージョンを渡す唯一の場合でも、いくつかのサーバサイドのページキャッシュでは - キャッシュされたコピーは有効期限が切れていないというだけの理由)
Djangoでは、修飾子を指定cache_controlビューにキャッシュパラメータを使用しています。この例では、キャッシュcache_controlは3600秒まで、各テストのバージョンをキャッシュに通知期限:
from django.views.decorators.cache import cache_control
@cache_control(must_revalidate=True, max_age=3600)
def my_view(request):
...
すべての法的に有効なすべてのCache - Control HTTPディレクティブcache_control()。次の命令の完全なリストです:
· public=True
· private=True
· no_cache=True
· no_transform=True
· must_revalidate=True
· proxy_revalidate=True
· max_age=num_seconds
· s_maxage=num_seconds
のCache - Control HTTPディレクティブの詳細を理解するために、Cache - Controlの仕様を参照してください。
(キャッシュミドルウェアは、キャッシュヘッダのmax - ageの設定値を設定することにより、最長寿命を持っていることに注意してください。Cache_control修飾子を、カスタムmax_ageを使用する場合、修飾子は優先順位の設定になり、ヘッダーの値が正常にマージされて)
· Django.middleware.http.ConditionalGetMiddlewareは、条件付きGETのためのサポートが追加されました。これは、ETagとLast - Modifiedヘッダーを使用しています。
· Django.middleware.gzip.GZipMiddlewareブラウザは(すべての一般的なブラウザがサポートされています)を送信するコンテンツのGzip圧縮をサポートしています。
MIDDLEWARE_CLASSES順
他にCacheMiddlewareはVaryヘッダミドルウェアに何かを追加することができる、ミドルウェアはVaryヘッダには、次のものを追加されます:
· SessionMiddlewareは、Cookieをプレイリストに追加しました。
· GZipMiddlewareはAccept - Encodingをプレイリストに追加しました。