キャッシュ アサイド パターン


Webサービスを多くのユーザに提供しているとパフォーマンスの問題にあたります。何度も同じデータを検索し同じ結果を返す。結果的にサーバの負荷がかかってしまうということになってきます。

そこで登場するのがキャッシュということになるのですが、ここでは常にキャッシュを最新化するパターンを紹介しようと思います。

キャッシュを使わない場合の問題

常にコストの高いデータベースへ問い合わせるためシステムの負荷が上がりパフォーマンスに影響を与えることがあります。

キャッシュを使う場合の利点

データベースへ問い合わせる代わりにコストの低いキャッシュサーバに保存しておいたデータを返すことでパフォーマンスの向上が期待できます。

流れ

  • データ取得時

    1. キャッシュがないかを確認
    2. キャッシュがある場合はキャッシュを応答
    3. キャッシュがない場合はデータを取得
    4. キャッシュに保存
    5. 応答
  • データ保存時

    1. データを更新する
    2. キャッシュを削除

実装イメージ

  • コードはイメージ的なものなので、実際のコードと置き換えてもらうと幸いです。
  • キャッシュはRedisなどのKVSに保存することを想定しています。
public class FooController : Controller{
    public FooController(ICatche catche, IFooService service){
         Catche = catche;
         Service = service;
    }

    private ICatche Catche{get;}

    private IFooService Service{get;}

    public Foo GetFoo(int id){
        var key = $"Foo:{id}";
        //キャッシュがあるかを確認
        if(Catche.Exists(key)){
            //存在すればキャッシュを返す
            return Catch.Get<Foo>(key);
        }

        // データを取得する
        Foo value = Service.Get(id);

        // キャッシュにデータを保存
        // 1時間の有効期限付き
        Catche.Set<Foo>(key, value, TimeSpan.FromHours(1));
        return value;
    }

    pubic void UpdateFoo(Foo value){
        var key = $"Foo:{id}";

        //Fooを更新する処理
        Service.Update(value);

        //キャッシュを削除
        Catche.Delete(key);
    }
}

参考サイト
キャッシュ アサイド パターン - Cloud Design Patterns | Microsoft Docs