Djangoパフォーマンス最適化:キャッシュ-(2)


せつぞく
まず、django-redisという名前のライブラリで接続できます.基本的に倉庫にbackendが内蔵されているmemcachedなどと異なり、第3部分庫を使用する.
python -m pip install django-redis
上記のようにライブラリをインストールします.settings/dev.pyなどのように、接続が必要な部分では以下のように接続されている.
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://<hostname>:<port>/<db_num>",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
キャッシュキー管理
ハードコーディング
キャッシュは、キーと対応する値で構成されます.典型的なキャッシュ使用パターンは次のとおりです.
def cached_scraps(self):
    data = cache.get(f"posts/{self.id}/scraps")
    if data is not None:
        return data
    else:
        qs = Scrap.objects.filter(post_id=self.id).values_list("user_id", flat=True)
        cache.set(f"posts/{self.id}/scraps", qs)
        return qs
上記ハードコーディングにより鍵を管理してもよい.プロジェクトの複雑さが高くなければ、悪くもありません.しかし,プロジェクトはますます膨大になり,同じ鍵を共有する場合が多くなるほど,メンテナンスが難しくなる.そこでおすすめの方法は以下の通りです.
ファイルとして管理
筆者はredis_key_schema.pyというファイルをアプリケーションごとに作成して使用することをお勧めします.後にkeyの形態を変える時も便利で、多方面に便利です.
def info_list(user):
    """
    format: `<username>:info-list
    """
    return f"{user}:info-list"


def board_list(user):
    """
    format: `<username>:board-list
    """
    return f"{user}:board-list"
このように使います.コードは上記のハードコーディングバージョンと似ています.
def list(self, request, *args, **kwargs):
    key = redis_key_schema.board_list(request.user)
    data = cache.get(key)

    if data:
        return Response(data)
    else:
        data = self.get_serializer(self.get_queryset(), many=True).data
        cache.set(key, data)
        return Response(data)
こうしてredis_key_schemaから導入・運用されている.以下のhas_keyの方法を使用することもできます.
def list(self, request, *args, **kwargs):
    key = redis_key_schema.board_list(request.user)
    
    if cache.has_key(key):
        return Response(cache.get(key))
    else:
        data = self.get_serializer(self.get_queryset(), many=True).data
        cache.set(key, data)
        return Response(data)
削除と更新
有効期限
一般に、cacheは、TTL(Time To Live)の構成によって管理される.これは、この時間が経過した後に期限が切れる方法です.前の設定ではtimeoutの値を変更して管理できますが、setにキャッシュされたときに設定することもできます.方式は以下の通り.
cache.set(key, value, timeout=60 * 60)
上記のように、各キーと値のペアは明示的にタイムアウトできます.
期限切れの強制
キャッシュを正しくクリアすることは、キャッシュを正しく取得することと同様に重要です.タイムリーな更新がなければ,ユーザは自分の動作がサーバに正しく反映されないと感じる.したがって、updatecreateなどの動作が完了した場合には、キャッシュを正しく消去することも重要である.
cache.delete(redis_key_schema.post(post_pk))