はじめに
APIのパフォーマンスは、ユーザーエクスペリエンスに直結します。この記事では、Python標準ライブラリのfunctools.lru_cache
を活用して、FastAPIアプリケーションにシンプルかつ効果的なキャッシュ機能を追加する方法を紹介します。
FastAPIでのキャッシュに関する注意事項
- 本記事では、Python標準ライブラリの
functools.lru_cache
を使用したシンプルなキャッシュ方法を紹介しています。 - FastAPI自体には、より高度なキャッシュ機能を提供するサードパーティ製ライブラリが存在します(例: fastapi-cache2)。この記事を作成するまえにわかっていませんでした。
- 今後の記事で、fastapi-cache2の詳細な解説を行う予定です。
lru_cacheとは?
lru_cache
は、関数の実行結果をキャッシュするためのデコレータです。「Least Recently Used(最も最近使われていない)」アルゴリズムに基づき、古いキャッシュデータを自動的に削除します。maxsize
パラメータでキャッシュの容量を制限できます。
lru_cacheが効果的なシナリオ
- 繰り返し呼び出される関数
- 計算コストが高い処理
- 結果の再利用が頻繁
基本的な使用例
from functools import lru_cache
@lru_cache(maxsize=100)
def expensive_computation(n: int):
return sum(i * i for i in range(n))
実際のユースケース
- 重い計算処理
- 予測モデルの結果の再利用
FastAPIとキャッシュを使ったAPIの実装
シーケンス図
コード例
import time
from fastapi import FastAPI, HTTPException
from functools import lru_cache
app = FastAPI()
@lru_cache(maxsize=100)
def expensive_computation(n: int):
return sum(i * i for i in range(n))
@app.get("/compute/{n}")
async def compute(n: int):
if n < 0:
raise HTTPException(status_code=400, detail="Input must be a non-negative integer。")
if n > 1000000:
raise HTTPException(status_code=400, detail="Input is too large for processing。")
start_time = time.time()
result = expensive_computation(n)
end_time = time.time()
execution_time_ms = (end_time - start_time) * 1000
return {
"result": result,
"execution_time_milliseconds": execution_time_ms
}
実装のポイント
- キャッシュの設定:
@lru_cache(maxsize=100)
- エラーハンドリング: 不適切な入力に対するエラー処理
- 処理時間の計測: キャッシュの効果を数値で確認
キャッシュの効果のテスト
# n=100000での初回リクエスト(キャッシュなし)
$ curl http://127.0.0.1:8000/compute/100000
# レスポンス: {"result": 333328333350000, "execution_time_milliseconds": 1234.56}
# 同じリクエストの2回目(キャッシュあり)
$ curl http://127.0.0.1:8000/compute/100000
# レスポンス: {"result": 333328333350000, "execution_time_milliseconds": 0.12}
まとめ
キャッシュの導入により、APIのパフォーマンスを劇的に向上させることができます。計算負荷の高いシステムやリアルタイム性が求められるアプリケーションでは特に有効です。
参考リンク
次回予告
次回の記事では、FastAPI向けのサードパーティ製キャッシュライブラリ「fastapi-cache2」の導入方法と高度な機能について解説します。(仮)