ASP.NET Core 분산 캐싱

Mohsin NasirSteve Smith

분산 캐시는 일반적으로 액세스하는 앱 서버에 대한 외부 서비스로 유지 관리되는 여러 앱 서버에서 공유하는 캐시입니다. 분산 캐시는 특히 앱이 클라우드 서비스 또는 서버 팜에서 호스트되는 경우 ASP.NET Core 앱의 성능과 확장성을 향상시킬 수 있습니다.

분산 캐시는 캐시된 데이터가 개별 앱 서버에 저장되는 다른 캐싱 시나리오에 비해 여러 가지 이점이 있습니다.

캐시된 데이터가 분산되면 데이터는 다음과 같습니다.

  • 여러 서버에 대한 요청 간에 일관되고 일관됩니다.
  • 서버 다시 시작 및 앱 배포가 남아 있습니다.
  • 로컬 메모리를 사용하지 않습니다.

분산 캐시 구성은 구현에 따라 다릅니다. 이 문서에서는 SQL Server 및 Redis 분산 캐시를 구성하는 방법을 설명합니다. NCache(GitHub NCache)와 같은타사구현도 사용할 수 있습니다. 선택한 구현에 관계없이 앱은 인터페이스를 사용하여 캐시와 상호 IDistributedCache 작용합니다.

예제 코드 살펴보기 및 다운로드 (다운로드 방법)

사전 요구 사항

SQL Server 분산 캐시를 사용하려면 Microsoft.Extensions.Caching.SqlServer 패키지에 패키지 참조를 추가합니다.

Redis 분산 캐시를 사용하려면 Microsoft.Extensions.Caching.StackExchangeRedis 패키지에 패키지 참조를 추가합니다.

NCache 분산 캐시를 사용하려면 NCache.Microsoft.Extensions.Caching.OpenSource 패키지에 패키지 참조를 추가합니다.

IDistributedCache 인터페이스

IDistributedCache인터페이스는 분산 캐시 구현의 항목을 조작하는 다음 메서드를 제공합니다.

  • Get, GetAsync : 문자열 키를 수락하고 캐시에 있는 경우 캐시된 항목을 byte[] 배열로 검색합니다.
  • Set, SetAsync : 문자열 키를 사용하여 캐시에 항목(배열)을 추가합니다. byte[]
  • Refresh, RefreshAsync : 키에 따라 캐시의 항목을 새로 고쳐 슬라이딩 만료 시간 제한(있는 경우)을 다시 설정합니다.
  • Remove, RemoveAsync : 해당 문자열 키에 따라 캐시 항목을 제거합니다.

분산 캐싱 서비스 설정

에서 의 IDistributedCache 구현을 Startup.ConfigureServices 등록합니다. 이 항목에서 설명하는 프레임워크 제공 구현은 다음과 같습니다.

분산 메모리 캐시

분산 메모리 AddDistributedMemoryCache 캐시()는 메모리에 항목을 저장하는 의 프레임워크 제공 IDistributedCache 구현입니다. 분산 메모리 캐시는 실제 분산 캐시가 아닙니다. 캐시된 항목은 앱이 실행되는 서버의 앱 인스턴스에 의해 저장됩니다.

분산 메모리 캐시는 유용한 구현입니다.

  • 개발 및 테스트 시나리오에서.
  • 프로덕션 및 메모리 사용에서 단일 서버를 사용하는 경우에는 문제가 되지 않습니다. 분산 메모리 캐시를 구현하는 것은 캐시된 데이터 스토리지를 추상화합니다. 여러 노드 또는 내결함성이 필요한 경우 나중에 진정한 분산 캐싱 솔루션을 구현할 수 있습니다.

샘플 앱은 앱이 의 개발 환경에서 실행될 때 분산 메모리 캐시를 사용합니다. Startup.ConfigureServices

services.AddDistributedMemoryCache();

분산 SQL Server 캐시

Distributed SQL Server Cache 구현( AddDistributedSqlServerCache )을 사용하면 분산 캐시에서 SQL Server 데이터베이스를 백업 저장소로 사용할 수 있습니다. SQL Server 인스턴스에서 SQL Server 캐시된 항목 테이블을 만들려면 도구를 사용할 수 sql-cache 있습니다. 이 도구는 지정한 이름과 스키마를 사용하여 테이블을 만듭니다.

명령을 실행하여 SQL Server 테이블을 sql-cache create 만듭니다. SQL Server 인스턴스( Data Source ), 데이터베이스( Initial Catalog ), 스키마(예: dbo ) 및 테이블 이름(예: TestCache )을 제공합니다.

dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

도구가 성공했음을 나타내는 메시지가 기록됩니다.

Table and index were created successfully.

도구에서 만든 sql-cache 테이블에는 다음 스키마가 있습니다.

SqlServer 캐시 테이블

참고

앱은 가 아닌 인스턴스를 사용하여 캐시 값을 조작해야 IDistributedCache SqlServerCache 합니다.

샘플 앱은 의 비 개발 환경에서 를 SqlServerCache 구현합니다. Startup.ConfigureServices

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = 
        _config["DistCache_ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

참고

ConnectionString(및 필요에 따라 SchemaNameTableName )는 일반적으로 소스 제어 외부에 저장됩니다(예: 비밀 관리자 또는 appsettings.json / appsettings에 저장). { ENVIRONMENT}.json 파일). 연결 문자열에는 소스 제어 시스템에서 유지해야 하는 자격 증명이 포함될 수 있습니다.

분산 Redis Cache

Redis는 분산 캐시로 자주 사용되는 오픈 소스 메모리 내 데이터 저장소입니다. Azure 호스팅 ASP.NET Core 앱에 대한 Azure Redis Cache 구성하고 로컬 개발에 Azure Redis Cache 사용할 수 있습니다.

앱은 인스턴스( )를 사용하여 캐시 구현을 RedisCache AddStackExchangeRedisCache 구성합니다.

  1. Azure Cache for Redis 만듭니다.
  2. 기본 연결 문자열(StackExchange.Redis)을 구성에 복사합니다.
    • 로컬 개발: 비밀 관리자를 통해 연결 문자열을 저장합니다.
    • Azure: App Service 구성 또는 다른 보안 저장소에 연결 문자열을 저장합니다.

다음 코드는 Azure Cache for Redis 사용하도록 설정합니다.

public void ConfigureServices(IServiceCollection services)
{
    if (_hostContext.IsDevelopment())
    {
        services.AddDistributedMemoryCache();
    }
    else
    {
        services.AddStackExchangeRedisCache(options =>
        {
            options.Configuration = _config["MyRedisConStr"];
            options.InstanceName = "SampleInstance";
        });
    }

    services.AddRazorPages();
}

위의 코드에서는 기본 연결 문자열(StackExchange.Redis)이 키 이름으로 구성에 저장되었다고 MyRedisConStr 가정합니다.

자세한 내용은 Azure Cache for Redis를 참조하세요.

로컬 Redis 캐시에 대한 대체 방법에 대한 설명은 이 GitHub 문제를 참조하세요.

분산 NCache 캐시

NCache는 .NET 및 .NET Core에서 기본적으로 개발된 오픈 소스 메모리 내 분산 캐시입니다. NCache는 로컬에서 작동하며 Azure 또는 다른 호스팅 플랫폼에서 실행되는 ASP.NET Core 앱에 대한 분산 캐시 클러스터로 구성됩니다.

로컬 컴퓨터에 NCache를 설치하고 구성하려면 Windows 시작 가이드(.NET 및 .NET Core)를참조하세요.

NCache를 구성하려면 다음을 수행합니다.

  1. NCache 오픈 소스 NuGet설치합니다.

  2. client.ncconf에서 캐시 클러스터를 구성합니다.

  3. 다음 코드를 Startup.ConfigureServices에 추가합니다.

    services.AddNCacheDistributedCache(configuration =>    
    {        
        configuration.CacheName = "demoClusteredCache";
        configuration.EnableLogs = true;
        configuration.ExceptionsEnabled = true;
    });
    

분산 캐시 사용

인터페이스를 사용하려면 IDistributedCache IDistributedCache 앱의 생성자에서 인스턴스를 요청합니다. 인스턴스는 DI(종속성 주입) 에서제공됩니다.

샘플 앱이 IDistributedCache 시작되면 가 에 삽입됩니다. Startup.Configure 현재 시간은 를 사용하여 IHostApplicationLifetime 캐시됩니다(자세한 내용은 일반 호스트: IHostApplicationLifetime참조).

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    IHostApplicationLifetime lifetime, IDistributedCache cache)
{
    lifetime.ApplicationStarted.Register(() =>
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
    });

샘플 앱은 IDistributedCache 인덱스 페이지에서 사용하기 위해 에 를 IndexModel 삽입합니다.

인덱스 페이지가 로드될 때마다 캐시는 에서 캐시된 시간 동안 OnGetAsync 확인됩니다. 캐시된 시간이 만료되지 않은 경우 시간이 표시됩니다. 캐시된 시간이 마지막으로 액세스된 시간(이 페이지가 마지막으로 로드된 시간) 이후 20초가 경과하면 페이지에 캐시된 시간 만료 가 표시됩니다.

캐시된 시간 다시 설정 단추를 선택하여 캐시된 시간을 현재 시간으로 즉시 업데이트합니다. 단추는 OnPostResetCachedTime 처리기 메서드를 트리거합니다.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

    public IndexModel(IDistributedCache cache)
    {
        _cache = cache;
    }

    public string CachedTimeUTC { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

참고

IDistributedCache인스턴스(적어도 기본 제공 구현의 경우)에 Singleton 또는 Scoped 수명을 사용할 필요가 없습니다.

IDistributedCacheDI를 사용하는 대신 인스턴스가 필요할 때마다 인스턴스를 만들 수도 있지만 코드에서 인스턴스를 만들면 코드를 테스트하기가 더 어려워지고 명시적 의존성 원칙을 위반할 수 있습니다.

권장 사항

의 구현이 IDistributedCache 앱에 가장 적합한지 결정할 때는 다음을 고려하세요.

  • 기존 인프라
  • 성능 요구 사항
  • 비용
  • 팀 환경

캐싱 솔루션은 일반적으로 메모리 내 스토리지를 사용하여 캐시된 데이터를 빠르게 검색하지만 메모리는 제한된 리소스이며 확장 비용이 많이 듭니다. 일반적으로 사용되는 데이터만 캐시에 저장합니다.

일반적으로 Redis 캐시는 SQL Server 캐시보다 높은 처리량과 짧은 대기 시간을 제공합니다. 그러나 일반적으로 캐싱 전략의 성능 특성을 확인하려면 벤치마킹이 필요합니다.

SQL Server 분산 캐시 백업 저장소로 사용되는 경우 캐시와 앱의 일반 데이터 스토리지 및 검색에 동일한 데이터베이스를 사용하면 두 가지 모두의 성능에 부정적인 영향을 줄 수 있습니다. 분산 캐시 백업 저장소에 전용 SQL Server 인스턴스를 사용 하는 것이 좋습니다.

추가 리소스

분산 캐시는 여러 앱 서버에서 공유 하는 캐시로, 일반적으로 액세스 하는 앱 서버에 외부 서비스로 유지 관리 됩니다. 분산 캐시는 특히 앱이 클라우드 서비스 또는 서버 팜에서 호스트 되는 경우 ASP.NET Core 앱의 성능과 확장성을 향상 시킬 수 있습니다.

분산 캐시는 개별 앱 서버에 캐시 된 데이터가 저장 되는 다른 캐싱 시나리오에 비해 여러 가지 이점을 제공 합니다.

캐시 된 데이터를 배포 하는 경우 데이터는 다음과 같습니다.

  • 는 여러 서버에 대 한 여러 요청 에서 일관 되 고 일관 됩니다.
  • 서버를 다시 시작 하 고 앱을 배포 합니다.
  • 로컬 메모리를 사용 하지 않습니다.

분산 캐시 구성은 구현 별로 다릅니다. 이 문서에서는 SQL Server 및 Redis 분산 캐시를 구성 하는 방법을 설명 합니다. NCache (NCache on GitHub)와 같은 타사 구현도 사용할 수 있습니다. 선택한 구현과 관계 없이 앱은 인터페이스를 사용 하 여 캐시와 상호 작용 합니다 IDistributedCache .

예제 코드 살펴보기 및 다운로드 (다운로드 방법)

사전 요구 사항

SQL Server 분산 캐시를 사용 하려면 Microsoft.AspNetCore.App 메타 패키지 를 참조 하거나 패키지 참조를 패키지에 추가 합니다.

Redis 분산 캐시를 사용 하려면 Microsoft.AspNetCore.App 메타 패키지 를 참조 하 고 StackExchangeRedis 패키지에 패키지 참조를 추가 합니다. Redis 패키지는 패키지에 포함 되지 Microsoft.AspNetCore.App 않으므로 프로젝트 파일에서 개별적으로 Redis 패키지를 참조 해야 합니다.

NCache 분산 캐시를 사용 하려면 Microsoft.AspNetCore.App 메타 패키지 를 참조 하 고 패키지 참조를 NCache 에 추가 합니다. NCache 패키지는 패키지에 포함 되지 Microsoft.AspNetCore.App 않으므로 프로젝트 파일에서 개별적으로 NCache 패키지를 참조 해야 합니다.

IDistributedCache 인터페이스

IDistributedCache인터페이스는 분산 캐시 구현에서 항목을 조작 하는 다음과 같은 메서드를 제공 합니다.

  • Get, GetAsync : 문자열 키를 허용 하 고 byte[] 캐시 된 항목을 캐시에 있는 경우 배열로 검색 합니다.
  • Set, SetAsync : byte[] 문자열 키를 사용 하 여 캐시에 항목 (배열)을 추가 합니다.
  • Refresh, RefreshAsync : 해당 키에 따라 캐시에서 항목을 새로 고쳐 슬라이딩 만료 시간 제한 (있는 경우)을 다시 설정 합니다.
  • Remove, RemoveAsync : 문자열 키를 기준으로 캐시 항목을 제거 합니다.

분산 캐싱 서비스 설정

에서의 구현을 등록 IDistributedCache Startup.ConfigureServices 합니다. 이 항목에서 설명 하는 프레임 워크 제공 구현에는 다음이 포함 됩니다.

분산 메모리 캐시

분산 메모리 캐시 ( AddDistributedMemoryCache )는 IDistributedCache 메모리에 항목을 저장 하는 프레임 워크에서 제공 하는 구현입니다. 분산 메모리 캐시는 실제 분산 된 캐시가 아닙니다. 캐시 된 항목은 앱이 실행 되 고 있는 서버의 앱 인스턴스에 의해 저장 됩니다.

분산 메모리 캐시는 다음과 같은 유용한 구현입니다.

  • 개발 및 테스트 시나리오에서
  • 프로덕션 환경에서 단일 서버를 사용 하는 경우 메모리 소비가 문제가 되지 않습니다. 분산 메모리 캐시를 구현 하면 캐시 된 데이터 저장소를 추상화 합니다. 이를 통해 여러 노드 또는 내결함성이 필요한 경우 나중에 진정한 분산 캐싱 솔루션을 구현할 수 있습니다.

샘플 앱은 앱이의 개발 환경에서 실행 될 때 분산 메모리 캐시를 사용 합니다 Startup.ConfigureServices .

services.AddDistributedMemoryCache();

분산 SQL Server 캐시

분산 SQL Server 캐시 구현 ( AddDistributedSqlServerCache )을 사용 하면 분산 캐시에서 SQL Server 데이터베이스를 백업 저장소로 사용할 수 있습니다. SQL Server 인스턴스에서 캐시 된 SQL Server 항목 테이블을 만들려면 도구를 사용할 수 있습니다 sql-cache . 이 도구는 사용자가 지정한 이름 및 스키마를 사용 하 여 테이블을 만듭니다.

명령을 실행 하 여 SQL Server에서 테이블을 만듭니다 sql-cache create . SQL Server 인스턴스 ( Data Source ), 데이터베이스 ( Initial Catalog ), 스키마 (예 dbo :) 및 테이블 이름 (예 TestCache :)을 제공 합니다.

dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

도구가 성공 했음을 나타내는 메시지가 기록 됩니다.

Table and index were created successfully.

도구에서 만든 테이블에는 sql-cache 다음 스키마가 있습니다.

SqlServer 캐시 테이블

참고

앱은가 아닌 인스턴스를 사용 하 여 캐시 값을 조작 해야 합니다 IDistributedCache SqlServerCache .

샘플 앱은 SqlServerCache 다음과 같은 개발 이외의 환경에서을 구현 합니다 Startup.ConfigureServices .

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = 
        _config["DistCache_ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

참고

ConnectionString(및 필요에 따라 SchemaNameTableName )는 일반적으로 소스 제어 외부에 저장 됩니다 (예: 암호 관리자 또는 appsettings에 의해 저장 됨) appsettings.json / . 환경}. json 파일). 연결 문자열에는 원본 제어 시스템에서 유지 되어야 하는 자격 증명이 포함 될 수 있습니다.

분산 Redis Cache

Redis 는 분산 캐시로 자주 사용 되는 오픈 소스 메모리 내 데이터 저장소입니다. Redis를 로컬로 사용할 수 있으며, Azure에서 호스트 되는 ASP.NET Core 앱에 대 한 Azure Redis Cache 를 구성할 수 있습니다.

앱은 RedisCache AddStackExchangeRedisCache 다음과 같은 개발 이외의 환경에서 인스턴스 ()를 사용 하 여 캐시 구현을 구성 합니다 Startup.ConfigureServices .

services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost";
    options.InstanceName = "SampleInstance";
});

로컬 컴퓨터에 Redis를 설치 하려면 다음을 수행 합니다.

  1. Chocolatey Redis 패키지를 설치 합니다.
  2. redis-server명령 프롬프트에서를 실행 합니다.

Distributed NCache Cache

NCache 는 .NET 및 .net Core에서 기본적으로 개발 된 오픈 소스 메모리 내 분산 캐시입니다. NCache는 로컬에서 작동 하 고 Azure 또는 다른 호스팅 플랫폼에서 실행 되는 ASP.NET Core 앱에 대 한 분산 캐시 클러스터로 구성 됩니다.

로컬 컴퓨터에 NCache를 설치 및 구성 하려면 시작 Windows 가이드 (.net 및 .net Core)를 참조 하세요.

NCache를 구성 하려면:

  1. NCache 오픈 소스 NuGet를 설치 합니다.

  2. Ncconf에서 캐시 클러스터를 구성 합니다.

  3. 다음 코드를 Startup.ConfigureServices에 추가합니다.

    services.AddNCacheDistributedCache(configuration =>    
    {        
        configuration.CacheName = "demoClusteredCache";
        configuration.EnableLogs = true;
        configuration.ExceptionsEnabled = true;
    });
    

분산 캐시 사용

인터페이스를 사용 하려면 IDistributedCache IDistributedCache 앱의 모든 생성자에서의 인스턴스를 요청 합니다. 인스턴스는 DI (종속성 주입)에 의해 제공 됩니다.

샘플 앱이 시작 되 면 IDistributedCache 가에 삽입 됩니다 Startup.Configure . 현재 시간은를 사용 하 여 캐시 됩니다. IApplicationLifetime 자세한 내용은 웹 호스트: IApplicationLifetime 인터페이스를 참조 하세요.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
    IApplicationLifetime lifetime, IDistributedCache cache)
{
    lifetime.ApplicationStarted.Register(() =>
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
    });

샘플 앱은 IDistributedCache IndexModel 인덱스 페이지에서 사용 하기 위해를에 삽입 합니다.

인덱스 페이지가 로드 될 때마다에서 캐시 된 시간에 대 한 캐시를 확인 합니다 OnGetAsync . 캐시 된 시간이 만료 되지 않은 경우에는 시간이 표시 됩니다. 캐시 된 시간에 마지막으로 액세스 한 후 20 초가 경과한 경우 (이 페이지가 마지막으로 로드 된 시간) 페이지에는 캐시 된 시간 만료 가 표시 됩니다.

캐시 된 시간 다시 설정 단추를 선택 하 여 캐시 된 시간을 현재 시간으로 즉시 업데이트 합니다. 단추는 OnPostResetCachedTime 처리기 메서드를 트리거합니다.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

    public IndexModel(IDistributedCache cache)
    {
        _cache = cache;
    }

    public string CachedTimeUTC { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

참고

인스턴스에 대해 Singleton 또는 범위 수명을 사용할 필요는 없습니다 IDistributedCache (최소한 기본 제공 구현의 경우).

IDistributedCacheDI를 사용 하는 대신 인스턴스를 만들 수도 있지만, 코드에서 인스턴스를 만들면 코드를 테스트 하는 것이 어렵고 명시적 종속성 원칙을 위반 하 게 될 수 있습니다.

권장 사항

IDistributedCache앱에 가장 적합 한 구현을 결정할 때 다음 사항을 고려 합니다.

  • 기존 인프라
  • 성능 요구 사항
  • 비용
  • 팀 환경

캐싱 솔루션은 일반적으로 메모리 내 저장소를 사용 하 여 캐시 된 데이터를 신속 하 게 검색 하지만 메모리는 제한 된 리소스 이며 확장 하는 데 비용이 많이 듭니다. 일반적으로 사용 되는 데이터를 캐시에만 저장 합니다.

일반적으로 Redis cache는 SQL Server 캐시 보다 높은 처리량과 짧은 대기 시간을 제공 합니다. 그러나 일반적으로 벤치마킹은 캐싱 전략의 성능 특성을 결정 하는 데 필요 합니다.

SQL Server를 분산 캐시 백업 저장소로 사용 하는 경우 캐시에 대해 동일한 데이터베이스를 사용 하 고 앱의 일반 데이터 저장 및 검색을 사용 하면 두 성능에 부정적인 영향을 줄 수 있습니다. 분산 캐시 백업 저장소에 전용 SQL Server 인스턴스를 사용 하는 것이 좋습니다.

추가 리소스

분산 캐시는 여러 앱 서버에서 공유 하는 캐시로, 일반적으로 액세스 하는 앱 서버에 외부 서비스로 유지 관리 됩니다. 분산 캐시는 특히 앱이 클라우드 서비스 또는 서버 팜에서 호스트 되는 경우 ASP.NET Core 앱의 성능과 확장성을 향상 시킬 수 있습니다.

분산 캐시는 개별 앱 서버에 캐시 된 데이터가 저장 되는 다른 캐싱 시나리오에 비해 여러 가지 이점을 제공 합니다.

캐시 된 데이터를 배포 하는 경우 데이터는 다음과 같습니다.

  • 는 여러 서버에 대 한 여러 요청 에서 일관 되 고 일관 됩니다.
  • 서버를 다시 시작 하 고 앱을 배포 합니다.
  • 로컬 메모리를 사용 하지 않습니다.

분산 캐시 구성은 구현 별로 다릅니다. 이 문서에서는 SQL Server 및 Redis 분산 캐시를 구성 하는 방법을 설명 합니다. NCache (NCache on GitHub)와 같은 타사 구현도 사용할 수 있습니다. 선택한 구현과 관계 없이 앱은 인터페이스를 사용 하 여 캐시와 상호 작용 합니다 IDistributedCache .

예제 코드 살펴보기 및 다운로드 (다운로드 방법)

사전 요구 사항

SQL Server 분산 캐시를 사용 하려면 Microsoft.AspNetCore.App 메타 패키지 를 참조 하거나 패키지 참조를 패키지에 추가 합니다.

Redis 분산 캐시를 사용 하려면 Microsoft.AspNetCore.App 메타 패키지 를 참조 하 고 Redis 패키지에 패키지 참조를 추가 합니다. Redis 패키지는 패키지에 포함 되지 Microsoft.AspNetCore.App 않으므로 프로젝트 파일에서 개별적으로 Redis 패키지를 참조 해야 합니다.

NCache 분산 캐시를 사용 하려면 Microsoft.AspNetCore.App 메타 패키지 를 참조 하 고 패키지 참조를 NCache 에 추가 합니다. NCache 패키지는 패키지에 포함 되지 Microsoft.AspNetCore.App 않으므로 프로젝트 파일에서 개별적으로 NCache 패키지를 참조 해야 합니다.

IDistributedCache 인터페이스

IDistributedCache인터페이스는 분산 캐시 구현에서 항목을 조작 하는 다음과 같은 메서드를 제공 합니다.

  • Get, GetAsync : 문자열 키를 허용 하 고 byte[] 캐시 된 항목을 캐시에 있는 경우 배열로 검색 합니다.
  • Set, SetAsync : byte[] 문자열 키를 사용 하 여 캐시에 항목 (배열)을 추가 합니다.
  • Refresh, RefreshAsync : 해당 키에 따라 캐시에서 항목을 새로 고쳐 슬라이딩 만료 시간 제한 (있는 경우)을 다시 설정 합니다.
  • Remove, RemoveAsync : 문자열 키를 기준으로 캐시 항목을 제거 합니다.

분산 캐싱 서비스 설정

에서의 구현을 등록 IDistributedCache Startup.ConfigureServices 합니다. 이 항목에서 설명 하는 프레임 워크 제공 구현에는 다음이 포함 됩니다.

분산 메모리 캐시

분산 메모리 캐시 ( AddDistributedMemoryCache )는 IDistributedCache 메모리에 항목을 저장 하는 프레임 워크에서 제공 하는 구현입니다. 분산 메모리 캐시는 실제 분산 된 캐시가 아닙니다. 캐시 된 항목은 앱이 실행 되 고 있는 서버의 앱 인스턴스에 의해 저장 됩니다.

분산 메모리 캐시는 다음과 같은 유용한 구현입니다.

  • 개발 및 테스트 시나리오에서
  • 프로덕션 환경에서 단일 서버를 사용 하는 경우 메모리 소비가 문제가 되지 않습니다. 분산 메모리 캐시를 구현 하면 캐시 된 데이터 저장소를 추상화 합니다. 이를 통해 여러 노드 또는 내결함성이 필요한 경우 나중에 진정한 분산 캐싱 솔루션을 구현할 수 있습니다.

샘플 앱은 앱이의 개발 환경에서 실행 될 때 분산 메모리 캐시를 사용 합니다 Startup.ConfigureServices .

services.AddDistributedMemoryCache();

분산 SQL Server 캐시

분산 SQL Server 캐시 구현 ( AddDistributedSqlServerCache )을 사용 하면 분산 캐시에서 SQL Server 데이터베이스를 백업 저장소로 사용할 수 있습니다. SQL Server 인스턴스에서 캐시 된 SQL Server 항목 테이블을 만들려면 도구를 사용할 수 있습니다 sql-cache . 이 도구는 사용자가 지정한 이름 및 스키마를 사용 하 여 테이블을 만듭니다.

명령을 실행 하 여 SQL Server에서 테이블을 만듭니다 sql-cache create . SQL Server 인스턴스 ( Data Source ), 데이터베이스 ( Initial Catalog ), 스키마 (예 dbo :) 및 테이블 이름 (예 TestCache :)을 제공 합니다.

dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache

도구가 성공 했음을 나타내는 메시지가 기록 됩니다.

Table and index were created successfully.

도구에서 만든 테이블에는 sql-cache 다음 스키마가 있습니다.

SqlServer 캐시 테이블

참고

앱은가 아닌 인스턴스를 사용 하 여 캐시 값을 조작 해야 합니다 IDistributedCache SqlServerCache .

샘플 앱은 SqlServerCache 다음과 같은 개발 이외의 환경에서을 구현 합니다 Startup.ConfigureServices .

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = 
        _config["DistCache_ConnectionString"];
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

참고

ConnectionString(및 필요에 따라 SchemaNameTableName )는 일반적으로 소스 제어 외부에 저장 됩니다 (예: 암호 관리자 또는 appsettings에 의해 저장 됨) appsettings.json / . 환경}. json 파일). 연결 문자열에는 원본 제어 시스템에서 유지 되어야 하는 자격 증명이 포함 될 수 있습니다.

분산 Redis Cache

Redis 는 분산 캐시로 자주 사용 되는 오픈 소스 메모리 내 데이터 저장소입니다. Redis를 로컬로 사용할 수 있으며, Azure에서 호스트 되는 ASP.NET Core 앱에 대 한 Azure Redis Cache 를 구성할 수 있습니다.

앱은 인스턴스 ()를 사용 하 여 캐시 구현을 구성 합니다 RedisCache AddDistributedRedisCache .

services.AddDistributedRedisCache(options =>
{
    options.Configuration = "localhost";
    options.InstanceName = "SampleInstance";
});

로컬 컴퓨터에 Redis를 설치 하려면 다음을 수행 합니다.

  1. Chocolatey Redis 패키지를 설치 합니다.
  2. redis-server명령 프롬프트에서를 실행 합니다.

Distributed NCache Cache

NCache 는 .NET 및 .net Core에서 기본적으로 개발 된 오픈 소스 메모리 내 분산 캐시입니다. NCache는 로컬에서 작동 하 고 Azure 또는 다른 호스팅 플랫폼에서 실행 되는 ASP.NET Core 앱에 대 한 분산 캐시 클러스터로 구성 됩니다.

로컬 컴퓨터에 NCache를 설치 및 구성 하려면 시작 Windows 가이드 (.net 및 .net Core)를 참조 하세요.

NCache를 구성 하려면:

  1. NCache 오픈 소스 NuGet를 설치 합니다.

  2. Ncconf에서 캐시 클러스터를 구성 합니다.

  3. 다음 코드를 Startup.ConfigureServices에 추가합니다.

    services.AddNCacheDistributedCache(configuration =>    
    {        
        configuration.CacheName = "demoClusteredCache";
        configuration.EnableLogs = true;
        configuration.ExceptionsEnabled = true;
    });
    

분산 캐시 사용

인터페이스를 사용 하려면 IDistributedCache IDistributedCache 앱의 모든 생성자에서의 인스턴스를 요청 합니다. 인스턴스는 DI (종속성 주입)에 의해 제공 됩니다.

샘플 앱이 시작 되 면 IDistributedCache 가에 삽입 됩니다 Startup.Configure . 현재 시간은를 사용 하 여 캐시 됩니다. IApplicationLifetime 자세한 내용은 웹 호스트: IApplicationLifetime 인터페이스를 참조 하세요.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
    IApplicationLifetime lifetime, IDistributedCache cache)
{
    lifetime.ApplicationStarted.Register(() =>
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
    });

샘플 앱은 IDistributedCache IndexModel 인덱스 페이지에서 사용 하기 위해를에 삽입 합니다.

인덱스 페이지가 로드 될 때마다에서 캐시 된 시간에 대 한 캐시를 확인 합니다 OnGetAsync . 캐시 된 시간이 만료 되지 않은 경우에는 시간이 표시 됩니다. 캐시 된 시간에 마지막으로 액세스 한 후 20 초가 경과한 경우 (이 페이지가 마지막으로 로드 된 시간) 페이지에는 캐시 된 시간 만료 가 표시 됩니다.

캐시 된 시간 다시 설정 단추를 선택 하 여 캐시 된 시간을 현재 시간으로 즉시 업데이트 합니다. 단추는 OnPostResetCachedTime 처리기 메서드를 트리거합니다.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

    public IndexModel(IDistributedCache cache)
    {
        _cache = cache;
    }

    public string CachedTimeUTC { get; set; }

    public async Task OnGetAsync()
    {
        CachedTimeUTC = "Cached Time Expired";
        var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

        if (encodedCachedTimeUTC != null)
        {
            CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
        }
    }

    public async Task<IActionResult> OnPostResetCachedTime()
    {
        var currentTimeUTC = DateTime.UtcNow.ToString();
        byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
        var options = new DistributedCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(20));
        await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

        return RedirectToPage();
    }
}

참고

인스턴스에 대해 Singleton 또는 범위 수명을 사용할 필요는 없습니다 IDistributedCache (최소한 기본 제공 구현의 경우).

IDistributedCacheDI를 사용 하는 대신 인스턴스를 만들 수도 있지만, 코드에서 인스턴스를 만들면 코드를 테스트 하는 것이 어렵고 명시적 종속성 원칙을 위반 하 게 될 수 있습니다.

권장 사항

IDistributedCache앱에 가장 적합 한 구현을 결정할 때 다음 사항을 고려 합니다.

  • 기존 인프라
  • 성능 요구 사항
  • 비용
  • 팀 환경

캐싱 솔루션은 일반적으로 메모리 내 저장소를 사용 하 여 캐시 된 데이터를 신속 하 게 검색 하지만 메모리는 제한 된 리소스 이며 확장 하는 데 비용이 많이 듭니다. 일반적으로 사용 되는 데이터를 캐시에만 저장 합니다.

일반적으로 Redis cache는 SQL Server 캐시 보다 높은 처리량과 짧은 대기 시간을 제공 합니다. 그러나 일반적으로 벤치마킹은 캐싱 전략의 성능 특성을 결정 하는 데 필요 합니다.

SQL Server를 분산 캐시 백업 저장소로 사용 하는 경우 캐시에 대해 동일한 데이터베이스를 사용 하 고 앱의 일반 데이터 저장 및 검색을 사용 하면 두 성능에 부정적인 영향을 줄 수 있습니다. 분산 캐시 백업 저장소에 전용 SQL Server 인스턴스를 사용 하는 것이 좋습니다.

추가 리소스