다음을 통해 공유


ASP.NET Core의 HybridCache 라이브러리

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

이 문서에서는 ASP.NET Core 앱에서 라이브러리를 HybridCache 구성하고 사용하는 방법을 설명합니다. 라이브러리에 대한 소개는 캐싱 개요 섹션을 참조 HybridCache 하세요.

라이브러리 가져오기

Microsoft.Extensions.Caching.Hybrid 패키지를 설치합니다.

dotnet add package Microsoft.Extensions.Caching.Hybrid --prerelease

서비스 등록

다음을 HybridCache 호출AddHybridCache하여 DI(종속성 주입) 컨테이너에 서비스를 추가합니다.

// Add services to the container.
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthorization();

builder.Services.AddHybridCache();

위의 코드는 기본 옵션으로 서비스를 등록합니다 HybridCache . 등록 API는 옵션 및 serialization을 구성할 수도 있습니다.

캐시 항목 가져오기 및 저장

HybridCache 서비스는 키를 사용하고 다음 두 오버로드가 있는 메서드를 제공합니다 GetOrCreateAsync .

  • 팩터리 메서드입니다.
  • 상태 및 팩터리 메서드입니다.

메서드는 키를 사용하여 기본 캐시에서 개체를 검색하려고 합니다. 기본 캐시(캐시 누락)에서 항목을 찾을 수 없는 경우 보조 캐시가 구성되어 있는지 확인합니다. 데이터가 없는 경우(다른 캐시 누락) 팩터리 메서드를 호출하여 데이터 원본에서 개체를 가져옵니다. 그런 다음 기본 및 보조 캐시에 개체를 저장합니다. 개체가 주 또는 보조 캐시(캐시 적중)에 있으면 팩터리 메서드가 호출되지 않습니다.

서비스는 HybridCache 지정된 키에 대한 동시 호출자 하나만 팩터리 메서드를 실행하고 다른 모든 호출자는 해당 실행 결과를 기다립니다. 전달된 GetOrCreateAsync 값은 CancellationToken 모든 동시 호출자의 결합된 취소를 나타냅니다.

GetOrCreateAsync 오버로드

대부분의 시나리오에서는 상태 비스테이스 오버로드 GetOrCreateAsync 를 사용하는 것이 좋습니다. 호출하는 코드는 비교적 간단합니다. 예를 들면 다음과 같습니다.

public class SomeService(HybridCache cache)
{
    private HybridCache _cache = cache;

    public async Task<string> GetSomeInfoAsync(string name, int id, CancellationToken token = default)
    {
        return await _cache.GetOrCreateAsync(
            $"{name}-{id}", // Unique key to the cache entry
            async cancel => await GetDataFromTheSourceAsync(name, id, cancel),
            token: token
        );
    }

    public async Task<string> GetDataFromTheSourceAsync(string name, int id, CancellationToken token)
    {
        string someInfo = $"someinfo-{name}-{id}";
        return someInfo;
    }
}

대체 GetOrCreateAsync 오버로드

대체 오버로드는 캡처된 변수 및 인스턴스별 콜백에서 약간의 오버헤드를 줄일 수 있지만, 더 복잡한 코드를 희생할 수 있습니다. 대부분의 시나리오에서 성능 향상은 코드 복잡성보다 크지 않습니다. 대체 오버로드를 사용하는 예제는 다음과 같습니다.

public class SomeService(HybridCache cache)
{
    private HybridCache _cache = cache;

    public async Task<string> GetSomeInfoAsync(string name, int id, CancellationToken token = default)
    {
        return await _cache.GetOrCreateAsync(
            $"{name}-{id}", // Unique key to the cache entry
            (name, id, obj: this),
            static async (state, token) =>
            await state.obj.GetDataFromTheSourceAsync(state.name, state.id, token),
            token: token
        );
    }

    public async Task<string> GetDataFromTheSourceAsync(string name, int id, CancellationToken token)
    {
        string someInfo = $"someinfo-{name}-{id}";
        return someInfo;
    }
}

SetAsync 메서드

많은 시나리오 GetOrCreateAsync 에서 필요한 유일한 API입니다. SetAsync 그러나 HybridCache 개체를 먼저 검색하지 않고 캐시에 저장해야 합니다.

노출되지 않은 캐시 항목 제거

캐시 항목의 기본 데이터가 만료되기 전에 변경되면 항목을 명시적으로 제거할 수 있습니다. 제거할 항목을 키로 지정할 수 있습니다. 항목이 제거되면 주 캐시와 보조 캐시 모두에서 제거됩니다.

키로 제거

다음 메서드는 키별 캐시 항목 제거를 지원합니다.

  • RemoveKeyAsync
  • RemoveKeysAsync

참고: 향후 변경될 예정 RemoveByKeyAsyncRemoveByKeysAsync 입니다.

옵션

이 메서드를 AddHybridCache 사용하여 전역 기본값을 구성할 수 있습니다. 다음 예제에서는 사용 가능한 옵션 중 일부를 구성하는 방법을 보여줍니다.

// Add services to the container.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorization();

builder.Services.AddHybridCache(options =>
    {
        options.MaximumPayloadBytes = 1024 * 1024;
        options.MaximumKeyLength = 1024;
        options.DefaultEntryOptions = new HybridCacheEntryOptions
        {
            Expiration = TimeSpan.FromMinutes(5),
            LocalCacheExpiration = TimeSpan.FromMinutes(5)
        };
    });

이 메서드는 GetOrCreateAsync 개체를 HybridCacheEntryOptions 사용하여 특정 캐시 항목에 대한 전역 기본값을 재정의할 수도 있습니다. 예를 들면 다음과 같습니다.

public class SomeService(HybridCache cache)
{
    private HybridCache _cache = cache;

    public async Task<string> GetSomeInfoAsync(string name, int id, CancellationToken token = default)
    {
        var tags = new List<string> { "tag1", "tag2", "tag3" };
        var entryOptions = new HybridCacheEntryOptions
        {
            Expiration = TimeSpan.FromMinutes(1),
            LocalCacheExpiration = TimeSpan.FromMinutes(1)
        };
        return await _cache.GetOrCreateAsync(
            $"{name}-{id}", // Unique key to the cache entry
            async cancel => await GetDataFromTheSourceAsync(name, id, cancel),
            entryOptions,
            tags,
            token: token
        );
    }
    
    public async Task<string> GetDataFromTheSourceAsync(string name, int id, CancellationToken token)
    {
        string someInfo = $"someinfo-{name}-{id}";
        return someInfo;
    }
}

옵션에 대한 자세한 내용은 소스 코드를 참조하세요.

제한

다음 속성을 HybridCacheOptions 사용하면 모든 캐시 항목에 적용되는 제한을 구성할 수 있습니다.

  • MaximumPayloadBytes - 캐시 항목의 최대 크기입니다. 기본값은 1MB입니다. 이 크기에 대한 값 저장 시도가 기록되고 값이 캐시에 저장되지 않습니다.
  • MaximumKeyLength - 캐시 키의 최대 길이입니다. 기본값은 1024자입니다. 이 크기에 대한 값 저장 시도가 기록되고 값이 캐시에 저장되지 않습니다.

직렬화

보조 out-of-process 캐시를 사용하려면 serialization이 필요합니다. 직렬화는 서비스 등록의 일부로 구성됩니다 HybridCache . 형식별 및 범용 직렬 변환기는 호출에서 연결된 메서드 및 WithSerializerFactory 메서드를 AddHybridCache 통해 WithSerializer 구성할 수 있습니다. 기본적으로 라이브러리는 내부적으로 처리 string 하고 byte[] 다른 모든 항목에 사용합니다 System.Text.Json . HybridCache 는 protobuf 또는 XML과 같은 다른 직렬 변환기를 사용할 수도 있습니다.

다음 예제에서는 형식별 protobuf 직렬 변환기를 사용하도록 서비스를 구성합니다.

// Add services to the container.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorization();

builder.Services.AddHybridCache(options =>
    {
        options.DefaultEntryOptions = new HybridCacheEntryOptions
        {
            Expiration = TimeSpan.FromSeconds(10),
            LocalCacheExpiration = TimeSpan.FromSeconds(5)
        };
    }).WithSerializer<SomeProtobufMessage, 
        GoogleProtobufSerializer<SomeProtobufMessage>>();

다음 예제에서는 많은 protobuf 형식을 처리할 수 있는 범용 protobuf 직렬 변환기를 사용하도록 서비스를 구성합니다.

// Add services to the container.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthorization();

builder.Services.AddHybridCache(options =>
{
    options.DefaultEntryOptions = new HybridCacheEntryOptions
    {
        Expiration = TimeSpan.FromSeconds(10),
        LocalCacheExpiration = TimeSpan.FromSeconds(5)
    };
}).WithSerializerFactory<GoogleProtobufSerializerFactory>();

보조 캐시에는 Redis 또는 SqlServer와 같은 데이터 저장소가 필요합니다. Azure Cache for Redis를 사용하려면 다음을 수행합니다.

  • Microsoft.Extensions.Caching.StackExchangeRedis 패키지를 설치합니다.

  • Azure Cache for Redis의 인스턴스를 만듭니다.

  • Redis 인스턴스에 연결하는 연결 문자열 가져옵니다. Azure Portal의 개요 페이지에서 액세스 키 표시를 선택하여 연결 문자열 찾습니다.

  • 앱의 구성에 연결 문자열 저장합니다. 예를 들어 다음 JSON과 같은 사용자 비밀 파일을 섹션의 연결 문자열 ConnectionStrings 사용합니다. 실제 연결 문자열 바꿉다<the connection string>.

    {
      "ConnectionStrings": {
        "RedisConnectionString": "<the connection string>"
      }
    }
    
  • Redis 패키지가 IDistributedCache 제공하는 구현을 DI에 등록합니다. 이렇게 하려면 호출AddStackExchangeRedisCache하고 연결 문자열 전달합니다. 예시:

    builder.Services.AddStackExchangeRedisCache(options =>
    {
        options.Configuration = 
            builder.Configuration.GetConnectionString("RedisConnectionString");
    });
    
  • Redis IDistributedCache 구현은 이제 앱의 DI 컨테이너에서 사용할 수 있습니다. HybridCache 는 보조 캐시로 사용하고 구성된 직렬 변환기를 사용합니다.

자세한 내용은 HybridCache serialization 샘플 앱을 참조 하세요.

캐시 스토리지

기본적으로 HybridCache 기본 캐시 스토리지에 사용됩니다 MemoryCache . 캐시 항목은 프로세스에 저장되므로 각 서버에는 서버 프로세스가 다시 시작될 때마다 손실되는 별도의 캐시가 있습니다. Redis 또는 SQL Server HybridCache 와 같은 보조 Out-of-process 스토리지의 경우 구성된 IDistributedCache 구현(있는 경우)을 사용합니다. 그러나 구현 HybridCacheIDistributedCache없더라도 서비스는 여전히 In-Process 캐싱 및 스탬피드 보호를 제공합니다.

성능 최적화

성능을 최적화하려면 개체를 다시 사용하고 할당을 방지 byte[] 하도록 구성 HybridCache 합니다.

개체 다시 사용

사용하는 IDistributedCache일반적인 기존 코드에서는 캐시에서 개체를 검색할 때마다 역직렬화가 발생합니다. 이 동작은 각 동시 호출자가 개체의 별도 인스턴스를 가져오며 다른 인스턴스와 상호 작용할 수 없음을 의미합니다. 동일한 개체 인스턴스를 동시에 수정할 위험이 없으므로 스레드 안전성도 발생합니다.

HybridCache 많은 사용량이 기존 IDistributedCache 코드 HybridCache 에서 조정되므로 동시성 버그가 발생하지 않도록 기본적으로 이 동작을 유지합니다. 그러나 다음과 같은 경우 개체는 기본적으로 스레드로부터 안전합니다.

  • 변경할 수 없는 형식입니다.
  • 코드는 수정하지 않습니다.

이러한 경우 다음을 통해 인스턴스를 다시 사용하는 것이 안전하다는 것을 알릴 HybridCache 수 있습니다.

  • 형식을 .로 표시 sealed합니다. C#의 키워드는 sealed 클래스를 상속할 수 없음을 의미합니다.
  • 형식에 [ImmutableObject(true)] 특성 적용 이 특성은 [ImmutableObject(true)] 개체를 만든 후에는 개체의 상태를 변경할 수 없음을 나타냅니다.

인스턴스 HybridCache 를 다시 사용하면 호출별 역직렬화와 관련된 CPU 및 개체 할당의 오버헤드를 줄일 수 있습니다. 이렇게 하면 캐시된 개체가 크거나 자주 액세스하는 시나리오에서 성능이 향상될 수 있습니다.

할당 방지 byte[]

HybridCache또한 할당을 방지하기 byte[] 위해 구현에 대한 IDistributedCache 선택적 API를 제공합니다. 이 기능은 미리 보기 버전의 및 Microsoft.Extensions.Caching.SqlServer 패키지에 Microsoft.Extensions.Caching.StackExchangeRedis 의해 구현됩니다. 자세한 내용은 IBufferDistributedCache 패키지를 설치하는 .NET CLI 명령은 다음과 같습니다.

dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis --prerelease
dotnet add package Microsoft.Extensions.Caching.SqlServer --prerelease

사용자 지정 HybridCache 구현

추상 클래스의 HybridCache 구체적인 구현은 공유 프레임워크에 포함되며 종속성 주입을 통해 제공됩니다. 그러나 개발자는 API의 사용자 지정 구현을 제공할 수 있습니다.

호환성

라이브러리는 .NET Framework 4.7.2 및 .NET Standard 2.0까지 이전 .NET 런타임을 지원합니다.

추가 리소스

자세한 HybridCache내용은 다음 리소스를 참조하세요.