しばらく前
に、キャッシングシステムについて書きました 。 私は続けることを約束したことを覚えていますが、コード行は数百のコメントよりも優れていると判断しました。理論は後で説明します。 したがって、本日、1本のボトルで使用するためのいくつかのヒントを記載した一種の発表があります。 cacheopsを満たす-Django ORMのキャッシュシステムと自動キャッシュ無効化。
前の記事を読んでいない、または単に忘れている人のための簡単な説明。 システムは、モデルオブジェクトの変更イベントでORMを介してデータベースへのクエリの結果を無効にし、イベントごとにどのクエリの結果が古くなる可能性があるかを自動的に判断するように設計されています。 自動無効化には、実際にはキャッシュの内容を除く追加の構造化情報を保存する必要があるため、
Redisがバックエンドとして選択されました。 これは実際的な発表なので、私は黙ってビジネスに取りかかります。
既にRedis、Djangoをインストールしており、キャッシュできるもの(モデルとそれらを使用するクエリ)があるとします。 cacheopsをインストールします。
pip install django-cacheops
または、まだコードを掘り下げることに決めた場合:
git clone git://github.com/Suor/django-cacheops.git ln -s `pwd`/django-cacheops/cacheops/ /somewhere/on/your/python/import/path/
次に、それを設定し、インストール済みアプリケーションのリストにcacheopsを追加する必要があります。 Cacheopsは、Djangoモデルをロードする前に初期化する必要があるため、最初に配置します。
INSTALLED_APPS = ( 'cacheops', ... )
大根接続とキャッシュプロファイルも設定する必要があります。
CACHEOPS_REDIS = { 'host': 'localhost',
キャッシュストレージ時間は頻繁に表示されますが、これはライフタイムの最大制限にすぎないことを理解することが重要です。実際の作業では、各特定のレコードはイベントのずっと早い段階で削除できます。
セットアップの準備ができました。続行できます。 実際、すでに使用できます。これらのタイプのすべてのリクエストはキャッシュされ、対応するモデルを変更、追加、削除すると自動的に無効になります。 ただし、個々のクエリセットのレベルでは、より微妙な使用が可能です。
手動キャッシュを使用できる最小設定として、次を使用できます。
CACHEOPS = { '*.*': ('just_enable', < >), }
これにより、次のような記述が可能になります。
articles = Article.objects.filter(tag=2).cache()
データベースへのリクエストを取得します。タグは、タグ2の記事を変更、追加、削除するときにキャッシュされ、データベースのキャッシュは消去されます。
キャッシュしてタイムアウトする必要がある一連の操作を.cache()メソッドに渡すことができます。
qs = Article.objects.filter(tag=2).cache(ops=['count'], timeout=60*5) paginator = Paginator(objects, ipp)
操作のセットは、空を含む['get'、 'fetch'、 'count']の任意のサブセットにすることができ、現在のクエリセットのキャッシュを無効にします。 ただし、後者の場合にはショートカットがあります:
qs = Article.objects.filter(visible=True).nocache()
ここでは、qsコンテンツへのアクセスはデータベースに移動します。
クエリセットに加えて、cacheopsは関数を操作でき、クエリセットとしてそれらを無効にできます。
from cacheops import cacheoped_as @cacheoped_as(Article.objects.all()) def article_stats(): return { 'tags': list( Article.objects.values('tag').annotate(count=Count('id')).nocache() ) 'categories': list( Article.objects.values('category').annotate(count=Count('id')).nocache() ) }
リスト内のクエリセットのラッピングに注意してください()-要求オブジェクトをキャッシュしたくないので、アクセスしようとするたびに実行されます。 また、.nocache()を使用して、あまり多くの作業を行わず、中間結果でキャッシュを詰まらせないようにします。
おそらく誰もが味を感じることができるように十分に与えたので、それが退屈になるまで停止します。
PS詳細を知りたい人のために-githubに
ロシア語のコメント付きの
ブランチがあります。