1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Azure] Redis Cache の実装

Last updated at Posted at 2022-04-09

パフォーマンスの向上のためにCacheを導入。 Readが多いjsonデータを扱うのにお勧め。

例えば、今全国の地域を表示するページがあります。都道府県がDBに格納されているのですが、ま・・そんなに変わるものではないのでDBに格納しておきながらもCache上にも持たせてページ表示のときはCacheのデータを見る、こんな動きを想定しています。

参照先

実装方法はここを参照しました。

まずは、キャッシュを管理するクライアントを作ります。Nuget上にそのライブラリーがありますのでそちらを使います。

Before

今どうなっているかというと。 こんな感じです。DBにアクセスして指定した国ID傘下にあるエリア一覧とそのエリア内にある都道府県をJoinして出力しています。


        /// <summary>
        /// Get regions by area id.
        /// </summary>
        /// <param name="areaId"></param>
        /// <param name="keyword"></param>
        /// <param name="sort"></param>
        /// <param name="currentPage"></param>
        /// <param name="itemsPerPage"></param>
        /// <returns></returns>
        public PaginationModel<RegionModel> GetRegionsByAreaId(string areaId, string keyword, string sort, int currentPage, int itemsPerPage)
        {
            var regions = from r in _db.Regions
                          join c in _db.AreaRegions on r.Id equals c.RegionId
                          where c.AreaId == areaId
                          select r;

            if (!string.IsNullOrEmpty(keyword))
            {
                regions = regions.Where(c => c.EnglishName.Contains(keyword));
            }

            if (string.IsNullOrEmpty(sort))
            {
                regions = regions.OrderBy(c => c.DisplayOrder);
            }

            int totalItems = regions.Count();
            int totalPages = 0;

            if (totalItems > 0)
            {
                totalPages = (totalItems / itemsPerPage) + 1;
            }

            var result = new PaginationModel<RegionModel>()
            {
                Items = regions.ToList(),
                Sort = sort,
                CurrentPage = currentPage,
                ItemsPerPage = itemsPerPage,
                Keyword = keyword,
                TotalItems = totalItems,
                TotalPages = totalPages
            };

            return result;
        }

After

今回はキャッシュあらかじめ検索結果を入れて置き、キャッシュにすでに同じ条件で出力したものが格納されているか確認、あればキャッシュから出す、この実装によってDBへの負荷を減らします。

該当したエリアやその傘下の都道府県情報が更新された際にはキャッシュも更新する必要がありますのでここは注意です。

下記のコードを別クラスで追加します。

  public class CacheServices
    {
        private static readonly string connectionStringUs = "";

        private static readonly Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
        {
            return ConnectionMultiplexer.Connect(connectionStringUs);
        });

        /// <summary>
        /// Returns ConnectionMultiplexer object
        /// </summary>
        public static ConnectionMultiplexer Connection => lazyConnection.Value;

    }

次に実際にエリアを取得するクラスにキャッシュから情報を取り出して出力するようにします。

   public async Task<PaginationModel<RegionModel>> GetRegionsByAreaIdAsync(string areaId, string keyword, string sort, int currentPage = 1, int itemsPerPage = 100)
        {

            // Only if keyword is null, let's try to find value in cahce.
            if (string.IsNullOrEmpty(keyword))
            {
                IDatabase cache = CacheServices.Connection.GetDatabase();
                var result = await cache.StringGetAsync("GetRegionsByAreaId-" + areaId);

                if (result.HasValue)
                {
                    var cacheReult = JsonSerializer.Deserialize<PaginationModel<RegionModel>>(result);

                    return cacheReult;
                }
                else
                {
                    // There was no data in cache, so fetch.
                    var dbResult = GetRegionsByAreaIdFromDb(areaId, keyword, sort, currentPage, itemsPerPage);

                    // And want to cache this.
                    string jsonString = JsonSerializer.Serialize(dbResult);
                    await cache.StringSetAsync("GetRegionsByAreaId-" + areaId, jsonString);

                    return dbResult;
                }
            }

            var dbresultWKeyword = GetRegionsByAreaIdFromDb(areaId, keyword, sort, currentPage, itemsPerPage);

            // And don't want to cache this.

            return dbresultWKeyword;
        }
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?