データベースクエリや外部 API 呼び出しの結果をキャッシュすることで、Flask アプリケーションのパフォーマンスを向上できる。Flask-Caching を使ったキャッシュ戦略を解説する。
Flask-Caching のセットアップ
pip install flask-caching
from flask import Flask from flask_caching import Cache app = Flask(__name__) app.config['CACHE_TYPE'] = 'SimpleCache' # 開発用 app.config['CACHE_DEFAULT_TIMEOUT'] = 300 # 5分 cache = Cache(app)
キャッシュバックエンドの選択
| SimpleCache | メモリ内キャッシュ(シングルプロセス向け) |
| FileSystemCache | ファイルシステムに保存 |
| RedisCache | Redis を使用(本番推奨) |
| MemcachedCache | Memcached を使用 |
本番環境では Redis を使う。
app.config['CACHE_TYPE'] = 'RedisCache' app.config['CACHE_REDIS_URL'] = 'redis://localhost:6379/0'
ビューのキャッシュ
@app.route('/posts') @cache.cached(timeout=60) def list_posts(): # このクエリ結果が60秒間キャッシュされる posts = Post.query.order_by(Post.created_at.desc()).all() return render_template('posts.html', posts=posts)
クエリパラメータを考慮
@app.route('/search') @cache.cached(timeout=60, query_string=True) def search(): q = request.args.get('q') # /search?q=flask と /search?q=python で別々にキャッシュ return {'results': perform_search(q)}
関数のキャッシュ(メモ化)
@cache.memoize(timeout=300) def get_user_stats(user_id): # 重い計算処理 return calculate_stats(user_id) # 呼び出し stats = get_user_stats(123) # 初回は計算 stats = get_user_stats(123) # キャッシュから取得
memoize は引数ごとにキャッシュを作成する。
キャッシュの手動操作
# 設定 cache.set('my_key', 'my_value', timeout=60) # 取得 value = cache.get('my_key') # 削除 cache.delete('my_key') # キーが存在しない場合のみ設定 cache.add('my_key', 'my_value')
キャッシュの無効化
# 特定のビューのキャッシュを削除 cache.delete_memoized(get_user_stats, 123) # 全キャッシュをクリア cache.clear()
キャッシュキーのカスタマイズ
def make_cache_key(): return f'user:{g.user.id}:dashboard' @app.route('/dashboard') @cache.cached(timeout=60, key_prefix=make_cache_key) def dashboard(): return render_template('dashboard.html')
キャッシュ戦略のパターン
リスト画面はキャッシュ、詳細画面は都度取得
更新頻度の低いマスタデータは長めにキャッシュ
ユーザーごとのデータはキャッシュキーにユーザー ID を含める
書き込み時にキャッシュを無効化
注意点
キャッシュはデータの整合性とのトレードオフである。更新が反映されないと困るデータはキャッシュしないか、短い TTL を設定する。また、キャッシュキーの設計を誤ると、あるユーザーのデータが別ユーザーに見えてしまう危険がある。