Computer >> 컴퓨터 >  >> 프로그래밍 >> Redis

통합 메모리 내 및 분산 캐싱을 위해 Redis를 사용하여 .NET 9에서 하이브리드 캐시 구축

하이브리드 캐시

하이브리드 캐시는 메모리 내 데이터와 외부 소스를 캐싱하기 위한 통합 라이브러리로, 다중 계층 캐싱이라고도 합니다. 즉, 이 다중 계층 캐싱은 IDistributedCache 및 IMemoryCache를 대체합니다. 또한 .NET에서 캐싱 사용을 단순화하기 위한 것입니다. 분산 캐싱에 대한 이전 접근 방식에서는 항목이 올바르게 캐시되고 검색되는지 확인하기 위해 추가 코드를 작성해야 했습니다. 이 패키지는 .NET의 캐싱을 단순화하여 강력한 캐싱 솔루션을 만드는 놀라운 추가 기능입니다. 우리는 Microsoft를 사용하여 하이브리드 캐시.Extensions.Caching.Hybrid 너겟 패키지를 구현합니다. 이 글에서는 하이브리드 캐시 패키지의 모든 기능을 다룰 것입니다.

패키지 기능

  • 확장 가능 코드: 인메모리 캐시용으로 작성된 코드는 Redis, SQL Server 등과 같은 외부 캐싱 서버와의 통합을 위해 수정 없이 그대로 사용할 수 있습니다.
  • 동시성 관리: 하이브리드 캐시를 사용하려면 하이브리드 캐시 클래스를 종속성 서비스로 사용해야 합니다. 이 클래스는 모든 키에 대한 데이터를 가져오는 데 인스턴스만 사용되며 동일한 항목에 대해 동시 요청이 이루어지지 않도록 보장합니다. 모든 동시 요청은 이 요청이 완료될 때까지 기다립니다.
  • 다중 소스 캐싱/1차-2차 소스 캐싱: 애플리케이션이 캐싱을 위해 여러 데이터 소스를 구성한 경우 데이터는 모든 위치에 저장됩니다.

데이터를 얻으려면 먼저 기본 소스에서 체크인해야 합니다. 해당 데이터를 사용할 수 없는 경우 아래 다이어그램에 표시된 대로 요청이 보조 소스로 전달됩니다(시나리오 1은 파란색, 시나리오 2는 빨간색).

코드 설정

시작하려면 먼저 Microsoft.Extensions.Caching.Hybrid 패키지를 설치하겠습니다.

Program.cs에서 하이브리드 캐시를 추가하기 위해 아래 코드를 작성하겠습니다.

builder.Services.AddHybridCache();

하이브리드 캐시를 구성하기 위해 설정 작업으로 AddHybridCache 내부에 아래 코드를 작성합니다. 아래는 예시입니다.

 builder.Services.AddHybridCache(options =>
 {
 options.ReportTagMetrics = true;
 options.DefaultEntryOptions = new Microsoft.Extensions.Caching.Hybrid.HybridCacheEntryOptions
 {
 Expiration = TimeSpan.FromSeconds(30),
 LocalCacheExpiration = TimeSpan.FromSeconds(30),
 
 };
 });

인메모리 캐시 구현

위의 종속성 서비스 구성은 메모리 내 캐싱을 수행하는 데 충분합니다. 다음은 애플리케이션 메모리에서 키와 값을 설정하고 가져오는 API 컨트롤러의 샘플 코드입니다.

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Hybrid;
namespace HybridCacheDemoApplication.Controllers
{
 [ApiController]
 [Route("[controller]")]
 public class CacheController : ControllerBase
 {
 private readonly HybridCache _cache;
 const string cacheKey = "ping";
 public CacheController(HybridCache cache)
 {
 _cache = cache;
 }
 [HttpGet(Name = "GetPingKey")]
 public async Task<IActionResult> Get()
 {
 var keydata = await _cache.GetOrCreateAsync<string>(
 cacheKey, // Unique key to the cache entry
 async cancel => await Task.FromResult("pong from get")
 );
 return Ok(new {message = $"{cacheKey} data: {keydata}"});
 }
 [HttpGet("set",Name = "SetPingKey")]
 public async Task<IActionResult> Set()
 {
 await _cache.SetAsync<string>(cacheKey, "ping");
 return Ok(new { message = $"{cacheKey} is set" });
 }
 }
}

이 코드의 작동 방식을 이해하려면 아래 표를 순서대로 참조하세요.

캐시 실행 데모 테이블
 

시퀀스 끝점 출력 설명 1 http://localhost:5154/cache/
{
 "message": "ping data: pong from get"
}
이 엔드포인트는 값이 설정되지 않은 경우 캐시 값을 "pong from get"으로 설정합니다. 따라서 "pong from get" 2 http://localhost:5154/cache/set
{
 "message": "ping is set"
}
을 인쇄합니다. 이 끝점은 캐시에 값을 설정합니다. 3 http://localhost:5154/cache/
{
 "message": "ping data: ping"
}
이는 1단계에서 호출한 것과 동일한 엔드포인트이지만 이번에는 값이 이미 캐시에 존재합니다.

캐시 키 삭제:캐시 키를 제거하려면 아래 구현을 사용합니다.

[HttpGet("del",Name="DeletePingKey")]
public async Task<IActionResult> RemoveKey()
{
 await _cache.RemoveAsync(cacheKey); //Removes data
 return Ok(new {message=$"{cacheKey} removed"});
}

Redis 서버를 이용한 분산 캐싱

분산 캐싱을 구현하려면 추가 종속성 서비스 구성을 수행해야 합니다. 이 예에서는 Redis 캐시를 외부 캐싱 소스로 사용합니다.

이제 Microsoft.Extensions.Caching.StackExchangeRedis를 사용하여 Redis 패키지를 구성하겠습니다

설치가 완료되면 Redis를 추가하기 위해 아래 코드를 추가해야 합니다. 연결 문자열은 {HOST_NAME}:{PORT_NUMBER},password={PASSWORD}

형식입니다.
 builder.Services.AddStackExchangeRedisCache(options =>
 {
 options.Configuration =
 builder.Configuration.GetConnectionString("RedisConnectionString");
 });

이제 http://localhost:5154/cache/set를 호출하면 데이터가 Redis 캐시에 원활하게 설정됩니다. 다음은 Redis에서 보이는 모습입니다

통합 메모리 내 및 분산 캐싱을 위해 Redis를 사용하여 .NET 9에서 하이브리드 캐시 구축

우리 시나리오에서 분산 캐싱 서버(예:Redis)에 대한 종속성을 추가하는 것만으로도 코드가 얼마나 원활하게 작동하는지 확인하세요.

직렬화

외부 캐싱 서버로 데이터를 보내기 위해 이 패키지는 byte[], 문자열 및 System.Text.Json을 사용합니다. 이는 AddHybridCache 종속성 서비스와 함께 .AddSerializer() 또는 AddSerializerFactory() 메서드를 추가로 사용하여 추가로 사용자 정의할 수 있습니다. 더욱 최적화된 직렬 변환기를 사용하면 애플리케이션 성능이 향상됩니다.

추가 맞춤설정

종속성을 구성할 때 플래그를 설정하여 캐시 서비스의 동작을 추가로 사용자 정의할 수 있습니다. 다음은 캐싱 압축을 비활성화하는 샘플 플래그입니다.

참고.  이는 모범 사례는 아니지만 압축이 필요하지 않거나 사용되지 않는 시나리오에 따라 달라질 수 있습니다.

 builder.Services.AddHybridCache(options =>
 {
 options.ReportTagMetrics = true;
 options.DefaultEntryOptions = new Microsoft.Extensions.Caching.Hybrid.HybridCacheEntryOptions
 {
 Flags = Microsoft.Extensions.Caching.Hybrid.HybridCacheEntryFlags.DisableCompression
 };
 });

실험적 기능:태그 - 상호 관련된 키 작업

때때로 우리는 서로 관련된 많은 키를 다룰 수도 있습니다. 예: 전자 상거래 애플리케이션에서는 장바구니 항목에 해당하는 많은 필드를 사용자에게 캐시했습니다. 이를 위해 태그를 만들 수 있습니다.

다음은 코드입니다. 상호 관련된 키로 작업하기 위해 "testdata"라는 태그를 만들었습니다. 다양한 시나리오에 적용할 수 있는 그룹화 유형에 따라 두 개 이상의 태그를 추가할 수 있습니다. 이 코드는 설명이 필요하지만 혼동되는 경우 댓글에서 언급해 주세요.

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Hybrid;
namespace HybridCacheDemoApplication.Controllers
{
 [ApiController]
 [Route("[controller]")]
 public class CacheController : ControllerBase
 {
 private readonly HybridCache _cache;
 const string cacheKey = "ping";
 public CacheController(HybridCache cache)
 {
 _cache = cache;
 }
 [HttpGet(Name = "GetPingKey")]
 public async Task<IActionResult> Get()
 {
 var keydata = await _cache.GetOrCreateAsync<string>(
 cacheKey, // Unique key to the cache entry
 async cancel => await Task.FromResult("pong from get"), 
 tags: ["testdata"]
 );
 return Ok(new {message = $"{cacheKey} data: {keydata}"});
 }
 [HttpGet("set",Name = "SetPingKey")]
 public async Task<IActionResult> Set()
 {
 await _cache.SetAsync<string>(cacheKey, 
 "ping", 
 tags: ["testdata"]
 );
 return Ok(new { message = $"{cacheKey} is set" });
 }
 [HttpGet("del",Name="DeletePingKey")]
 public async Task<IActionResult> RemoveKey()
 {
 await _cache.RemoveAsync(cacheKey);
 return Ok(new {message=$"{cacheKey} removed"});
 }
 [HttpGet("delbytag", Name = "DeleteByTestTags")]
 public async Task<IActionResult> RemoveKeyByTags()
 {
 await _cache.RemoveByTagAsync(["testdata"]);
 return Ok(new { message = $"{cacheKey} removed" });
 }
 }
}

끝까지 읽어주셔서 감사합니다. 이 하이브리드 캐싱은 놀라운 이점을 제공하므로 귀하도 이 내용이 도움이 되기를 바랍니다.