
들어가며
ASP.NET Core 애플리케이션을 개발할 때 가장 큰 고민 중 하나는 바로 성능입니다. 애플리케이션이 성장하고 사용자가 늘어날수록 데이터베이스는 같은 데이터를 반복해서 조회하게 되고, 이는 응답 속도 저하와 서버 부하 증가로 이어집니다.
이러한 문제를 해결해 주는 것이 바로 Redis를 활용한 분산 캐싱입니다.
매번 데이터베이스에 요청하는 대신 자주 사용되는 데이터를 Redis처럼 빠른 인메모리 시스템에 저장해 두면, 다음에 동일한 데이터가 요청될 때 데이터베이스가 아닌 캐시에서 즉시 반환할 수 있습니다.
이 글에서는 ASP.NET Core에서 Redis 분산 캐싱을 단계별로, 실무에서 바로 적용할 수 있도록 쉽게 설명합니다.
분산 캐싱이란 무엇인가?
분산 캐싱(Distributed Caching)은 캐시 데이터를 애플리케이션 외부의 별도 서비스(예: Redis)에 저장하는 방식을 말합니다.
일반적인 인메모리 캐시는 단일 서버 내부에만 데이터를 저장합니다. 애플리케이션이 여러 대의 서버에서 실행된다면 각 서버마다 별도의 캐시가 생기게 되며, 이는 데이터 불일치 문제를 일으킬 수 있습니다.
반면 분산 캐싱은 다음과 같은 장점이 있습니다.
- 모든 서버가 하나의 캐시를 공유합니다
- 애플리케이션 전반에서 데이터 일관성이 유지됩니다
- 확장 가능한 환경에서 효과적으로 동작합니다
쉽게 말해 분산 캐시는 모든 애플리케이션 서버가 함께 사용할 수 있는 공유 메모리라고 생각하면 됩니다.
Redis란 무엇인가?
Redis는 매우 빠른 인메모리 데이터 저장소로, 캐싱 용도로 널리 사용됩니다.
Redis를 초고속 사전(Dictionary)이라고 생각해 보세요.
- 키(Key)를 사용해 데이터를 저장하고
- 같은 키로 데이터를 조회합니다
개발자들이 Redis를 선호하는 이유
- 데이터를 메모리에 저장하기 때문에 매우 빠릅니다
- 단순한 키-값 저장 방식을 지원합니다
- ASP.NET Core와 손쉽게 통합됩니다
- 확장형 및 클라우드 기반 애플리케이션에 적합합니다
사전 준비 사항
시작하기 전에 다음 항목들이 준비되어 있는지 확인하세요.
- 시스템에 설치된 .NET SDK
- 동작 중인 ASP.NET Core 프로젝트
- 로컬에 설치된 Redis 또는 클라우드 Redis 서비스 접근 권한
- ASP.NET Core의 컨트롤러와 서비스에 대한 기본 이해
로컬에 Redis가 없다면 Docker를 사용하거나 클라우드 제공업체를 활용할 수 있습니다.
1단계: 필요한 NuGet 패키지 설치
먼저 Redis 캐싱 패키지를 설치해야 합니다. 다음 명령어를 실행하세요.
dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis
이 패키지는 ASP.NET Core 애플리케이션과 Redis를 연결하고 분산 캐싱 기능을 사용할 수 있게 해 줍니다.
2단계: ASP.NET Core에서 Redis 구성
다음으로, 애플리케이션이 Redis에 연결하는 방법을 설정해야 합니다.
Program.cs 파일을 열고 아래 설정을 추가하세요.
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost:6379";
options.InstanceName = "SampleApp_";
});
설정 항목 살펴보기
localhost:6379→ Redis가 실행 중인 주소입니다InstanceName→ 모든 캐시 키에 붙는 접두사로, 데이터 정리에 유용합니다
클라우드 Redis를 사용하는 경우 localhost 값을 실제 연결 문자열로 교체하면 됩니다.
3단계: IDistributedCache 서비스 주입
ASP.NET Core는 Redis와 작업하기 위한 내장 인터페이스인 IDistributedCache를 제공합니다.
이 인터페이스를 서비스나 컨트롤러에 주입하여 사용합니다.
public class ProductService
{
private readonly IDistributedCache _cache;
public ProductService(IDistributedCache cache)
{
_cache = cache;
}
}
이렇게 하면 해당 클래스가 Redis와 통신할 수 있게 됩니다.
4단계: Redis 캐시에 데이터 저장
Redis에 데이터를 저장하려면 SetStringAsync 메서드를 사용합니다.
public async Task SetCacheDataAsync(string key, string value)
{
var options = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10)
};
await _cache.SetStringAsync(key, value, options);
}
코드 설명
- 고유한 키를 사용해 데이터를 저장합니다
- 만료 시간(10분)을 설정합니다
만료 시간이 중요한 이유
- 오래된 데이터 사용을 방지합니다
- 캐시를 깨끗하게 유지합니다
- 메모리를 절약합니다
5단계: 캐시에서 데이터 조회
Redis에서 데이터를 가져오려면 다음 코드를 사용합니다.
public async Task<string> GetCacheDataAsync(string key)
{
return await _cache.GetStringAsync(key);
}
데이터가 존재하면 즉시 반환되고, 존재하지 않으면 null을 반환합니다. 데이터베이스를 직접 호출하는 것보다 훨씬 빠릅니다.
6단계: Cache-Aside 패턴 구현
캐싱을 활용하는 가장 일반적인 방식은 Cache-Aside(캐시 어사이드) 패턴입니다.
동작 순서는 다음과 같습니다.
- 먼저 캐시를 확인합니다
- 데이터가 존재하면 → 캐시에서 반환합니다
- 존재하지 않으면 → 데이터베이스에서 조회한 뒤 캐시에 저장합니다
구현 예제
public async Task<string> GetProductAsync(string productId)
{
string cacheKey = $"product_{productId}";
var cachedData = await _cache.GetStringAsync(cacheKey);
if (!string.IsNullOrEmpty(cachedData))
{
return cachedData;
}
var productData = "Product from Database";
await _cache.SetStringAsync(cacheKey, productData, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
});
return productData;
}
이 패턴의 장점
- 데이터베이스 호출 횟수를 줄입니다
- 응답 시간을 개선합니다
- 필요할 때 자동으로 캐시를 채웁니다
7단계: 복잡한 객체 다루기
Redis는 데이터를 문자열 형태로 저장하므로, 객체를 저장하려면 JSON으로 변환해야 합니다.
public async Task SetObjectAsync<T>(string key, T data)
{
var jsonData = JsonSerializer.Serialize(data);
await _cache.SetStringAsync(key, jsonData);
}
public async Task<T> GetObjectAsync<T>(string key)
{
var jsonData = await _cache.GetStringAsync(key);
return jsonData == null ? default : JsonSerializer.Deserialize<T>(jsonData);
}
정리하면 다음과 같습니다.
- 객체 → JSON 직렬화 → Redis에 저장
- JSON 조회 → 객체로 역직렬화
8단계: 캐시에서 데이터 삭제
때로는 오래되었거나 잘못된 캐시 데이터를 삭제해야 할 때가 있습니다.
await _cache.RemoveAsync("product_1");
다음과 같은 상황에서 유용합니다.
- 데이터베이스의 데이터가 업데이트되었을 때
- 캐시가 더 이상 유효하지 않을 때
9단계: Redis 캐싱 모범 사례
Redis를 효과적으로 사용하려면 다음 사례들을 따르는 것이 좋습니다.
- 명확하고 고유한 캐시 키를 사용합니다
- 항상 만료 시간을 설정합니다
- 민감한 데이터는 캐싱하지 않습니다
- 너무 큰 객체 저장은 피합니다
- 캐시 사용량과 성능을 지속적으로 모니터링합니다
이러한 습관은 성능 유지와 향후 문제 예방에 큰 도움이 됩니다.
10단계: 대표적인 활용 사례
Redis 캐싱은 다음과 같은 경우에 널리 사용됩니다.
- API 응답 캐싱
- 상품 목록 조회
- 사용자 세션 관리
- 자주 조회되는 데이터
- 대시보드 데이터
읽기는 잦지만 변경은 드문 데이터라면 캐싱하기에 좋은 후보입니다.
ASP.NET Core에서 Redis를 사용하는 장점
Redis를 도입하면 다음과 같은 이점을 얻을 수 있습니다.
- 더 빠른 애플리케이션 성능
- 데이터베이스 부하 감소
- 향상된 확장성
- 개선된 사용자 경험
특히 트래픽이 많은 애플리케이션에서 그 효과가 두드러집니다.
마치며
ASP.NET Core에서 Redis를 활용한 분산 캐싱은 애플리케이션 성능을 개선하는 간단하면서도 강력한 방법입니다. 데이터베이스를 반복적으로 호출하는 대신 자주 사용되는 데이터를 Redis에 저장해 두면, 필요할 때 빠르게 조회할 수 있습니다.
이 글에서 소개한 단계별 접근법과 Cache-Aside 패턴, 그리고 모범 사례를 활용하면 빠르고 확장 가능하며 효율적인 애플리케이션을 만들 수 있습니다. 작은 부분부터 시작해 성능에 가장 큰 영향을 주는 곳에 캐싱을 적용하고, 점진적으로 시스템을 최적화해 나가시기 바랍니다.