WEB - PHP, JQuery, Bootstrap

.NET Core에서 MemoryCache를 활용한 Backend 캐시 구현 가이드

초심으로 2024. 9. 13. 14:00

728x90

웹 애플리케이션에서 자주 호출되는 데이터는 서버 성능에 영향을 줄 수 있습니다. 특히 자주 변경되지 않는 데이터를 데이터베이스에서 반복적으로 불러오는 대신, 캐시(Cache) 에 저장해 두면 성능을 최적화할 수 있습니다. 이번 글에서는 .NET Core에서 MemoryCache를 사용해 데이터를 캐싱하고, 항목별로 캐시 만료 시간을 다르게 설정하는 방법을 알아보겠습니다.


1. MemoryCache란?

MemoryCache는 .NET Core에서 제공하는 메모리 기반의 캐싱 기술로, 데이터를 서버 메모리에 저장하여 빠르게 조회할 수 있도록 돕습니다. 자주 변경되지 않는 데이터를 캐시에 저장함으로써 데이터베이스나 외부 API 호출을 줄여 성능을 향상시킬 수 있습니다. 특히, 각 데이터마다 다른 만료 시간을 설정할 수 있는 유연함이 장점입니다.

MemoryCache 사용의 장점

  • 성능 최적화: 데이터베이스 호출을 줄이고, 자주 사용하는 데이터를 메모리에서 빠르게 조회할 수 있습니다.
  • 항목별 만료 설정: 각 항목마다 서로 다른 캐시 만료 시간을 설정할 수 있습니다.
  • 간단한 구현: 코드에서 간단하게 캐시를 적용할 수 있으며, 확장성 있는 관리가 가능합니다.

2. .NET Core에서 MemoryCache 설정하기

MemoryCache는 .NET Core에서 Microsoft.Extensions.Caching.Memory 패키지를 통해 제공됩니다. 이 패키지를 사용해 캐시를 설정하고 데이터를 관리하는 방법을 알아보겠습니다.

1) 프로젝트에 패키지 추가

먼저, MemoryCache를 사용하기 위해 Microsoft.Extensions.Caching.Memory 패키지가 프로젝트에 설치되어 있는지 확인해야 합니다.

dotnet add package Microsoft.Extensions.Caching.Memory

2) 서비스 등록

.NET Core에서는 DI(의존성 주입) 방식을 통해 MemoryCache를 사용합니다. Startup.cs 파일에서 캐시 서비스를 등록합니다.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMemoryCache(); // MemoryCache 등록
        services.AddControllersWithViews(); // MVC 패턴 사용
    }
}

3. MemoryCache를 이용한 캐시 로직 구현

캐시 서비스를 컨트롤러나 서비스에 주입받아 사용하며, 항목별로 다른 만료 시간을 설정할 수 있습니다.

CacheService 클래스 구현

using Microsoft.Extensions.Caching.Memory;
using System;

public class CacheService
{
    private readonly IMemoryCache _cache;

    public CacheService(IMemoryCache cache)
    {
        _cache = cache;
    }

    // 캐시에 데이터를 저장하는 메서드
    public void SetCacheItem(string key, object value, int durationInMinutes)
    {
        var cacheEntryOptions = new MemoryCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(durationInMinutes)
        };

        _cache.Set(key, value, cacheEntryOptions);
    }

    // 캐시에서 데이터를 가져오는 메서드
    public object GetCacheItem(string key)
    {
        return _cache.TryGetValue(key, out var value) ? value : null;
    }

    // 캐시에서 데이터를 삭제하는 메서드
    public void RemoveCacheItem(string key)
    {
        _cache.Remove(key);
    }
}

주요 설명:

  • SetCacheItem: 캐시에 데이터를 저장하며, 항목별로 만료 시간을 설정할 수 있습니다.
  • GetCacheItem: 캐시에서 데이터를 조회하고, 캐시된 데이터가 없으면 null을 반환합니다.
  • RemoveCacheItem: 캐시에 저장된 데이터를 삭제합니다.

4. 컨트롤러에서 MemoryCache 적용하기

이제 위에서 작성한 CacheService를 컨트롤러에 주입하여, 각 항목별로 다른 만료 시간을 적용한 캐시 기능을 구현해보겠습니다.

예시: HomeController에서 캐시 사용하기

using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller
{
    private readonly CacheService _cacheService;

    public HomeController(CacheService cacheService)
    {
        _cacheService = cacheService;
    }

    // 제품 목록은 30분, 사용자 프로필은 10분 동안 캐시
    public IActionResult Index()
    {
        string productCacheKey = "ProductList";
        string userProfileCacheKey = "UserProfile";

        // 제품 목록 캐시 조회
        var products = _cacheService.GetCacheItem(productCacheKey);
        if (products == null)
        {
            // 캐시에 없으면 데이터베이스에서 가져오고, 30분 동안 캐시
            products = "This is the product list from the database.";
            _cacheService.SetCacheItem(productCacheKey, products, 30);  // 30분 캐시
        }

        // 사용자 프로필 캐시 조회
        var userProfile = _cacheService.GetCacheItem(userProfileCacheKey);
        if (userProfile == null)
        {
            // 캐시에 없으면 데이터베이스에서 가져오고, 10분 동안 캐시
            userProfile = "This is the user profile from the database.";
            _cacheService.SetCacheItem(userProfileCacheKey, userProfile, 10);  // 10분 캐시
        }

        ViewBag.Products = products;
        ViewBag.UserProfile = userProfile;

        return View();
    }

    // 캐시 삭제
    public IActionResult ClearCache()
    {
        _cacheService.RemoveCacheItem("ProductList");
        _cacheService.RemoveCacheItem("UserProfile");

        ViewBag.Message = "캐시가 성공적으로 삭제되었습니다.";
        return RedirectToAction("Index");
    }
}

주요 설명:

  • Index 액션:
    • 제품 목록(ProductList)은 30분 동안 캐시되고, 사용자 프로필(UserProfile)은 10분 동안 캐시됩니다.
    • 캐시에서 데이터를 먼저 조회하고, 없을 경우 데이터베이스에서 데이터를 가져와 캐시에 저장합니다.
  • ClearCache 액션:
    • ProductListUserProfile 캐시 데이터를 삭제하고, 성공 메시지를 보여줍니다.

5. 캐시 만료 시간 항목별 설정

MemoryCacheEntryOptions를 통해 캐시 항목별로 서로 다른 만료 시간을 설정할 수 있습니다. 이때 AbsoluteExpirationRelativeToNow 옵션을 사용하여 캐시 만료 시간을 지정합니다.

var cacheEntryOptions = new MemoryCacheEntryOptions
{
    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(durationInMinutes)
};
_cache.Set(key, value, cacheEntryOptions);

이 외에도 SlidingExpiration을 설정하여 마지막으로 캐시 항목이 접근된 시점부터 일정 시간이 지나면 만료되도록 할 수도 있습니다.


6. 캐시 활용의 시나리오 예시

자주 변경되지 않는 데이터의 캐싱

  • 제품 목록: 제품 목록은 자주 변경되지 않으므로, 30분 정도 캐시하여 데이터베이스 부하를 줄일 수 있습니다.
  • 사용자 프로필: 사용자 프로필은 자주 변경될 수 있으므로, 10분 정도만 캐시합니다.

7. MemoryCache의 한계와 주의사항

  • 메모리 사용: MemoryCache는 서버 메모리를 사용하므로, 너무 많은 데이터를 오랫동안 캐시하면 메모리가 부족해질 수 있습니다. 필요한 데이터만 캐싱하는 것이 중요합니다.
  • 분산 캐시 필요: 여러 서버에서 애플리케이션이 실행되는 경우, 각 서버의 캐시가 독립적으로 동작하므로 데이터 동기화가 필요할 수 있습니다. 이럴 때는 Redis와 같은 분산 캐시 솔루션을 사용하는 것이 좋습니다.

결론

이 글에서는 .NET Core에서 MemoryCache를 사용해 데이터를 캐싱하고, 항목별로 캐시 만료 시간을 설정하는 방법을 알아봤습니다. 캐싱은 애플리케이션의 성능을 크게 향상시킬 수 있는 기술이며, 항목별로 적절한 만료 시간을 설정하면 더 효과적으로 애플리케이션을 관리할 수 있습니다.

핵심 요약:

  • MemoryCache는 데이터베이스 접근을 줄이고 성능을 개선하는 데 중요한 역할을 합니다.
  • 항목별 캐시 만료 시간을 설정할 수 있어 데이터 특성에 맞게 유연하게 관리할 수 있습니다.
  • 적절한 만료 시간 설정과 메모리 관리를 통해 효율적인 캐시 전략을 구성하는 것이 중요합니다.

이제 이 가이드를 실무에 적용해 성능을 최적화하고, 캐싱 전략을 활용해보세요!

반응형