Buforowanie rozproszone w ASP.NET Core

Przez Mohsin Nasir i smandia

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Rozproszona pamięć podręczna to pamięć podręczna współużytkowana przez wiele serwerów aplikacji, zwykle utrzymywana jako usługa zewnętrzna dla serwerów aplikacji, które uzyskują do niej dostęp. Rozproszona pamięć podręczna może zwiększyć wydajność i skalowalność aplikacji ASP.NET Core, zwłaszcza gdy aplikacja jest hostowana przez usługę w chmurze lub farmę serwerów.

Rozproszona pamięć podręczna ma kilka zalet w przypadku innych scenariuszy buforowania, w których buforowane dane są przechowywane na poszczególnych serwerach aplikacji.

Gdy buforowane dane są dystrybuowane, dane:

  • Jest spójna (spójna ) między żądaniami na wielu serwerach.
  • Przetrwa ponowne uruchomienie serwera i wdrożenia aplikacji.
  • Nie używa pamięci lokalnej.

Konfiguracja rozproszonej pamięci podręcznej jest specyficzna dla implementacji. W tym artykule opisano sposób konfigurowania rozproszonych pamięci podręcznych sql Server i Redis. Dostępne są również implementacje innych firm, takie jak NCache (NCache w usłudze GitHub). Niezależnie od wybranej implementacji aplikacja współdziała z pamięcią podręczną przy użyciu interfejsu IDistributedCache .

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

Dodaj odwołanie do pakietu dla używanego dostawcy rozproszonej pamięci podręcznej:

IDistributedCache, interfejs

Interfejs IDistributedCache udostępnia następujące metody manipulowania elementami w implementacji rozproszonej pamięci podręcznej:

  • Get, GetAsync: akceptuje klucz ciągu i pobiera buforowany element jako tablicę byte[] , jeśli zostanie znaleziony w pamięci podręcznej.
  • Set, SetAsync: dodaje element (jako byte[] tablicę) do pamięci podręcznej przy użyciu klucza ciągu.
  • Refresh, RefreshAsync: odświeża element w pamięci podręcznej na podstawie jego klucza, resetując jego przesuwany limit czasu wygaśnięcia (jeśli istnieje).
  • Remove, RemoveAsync: usuwa element pamięci podręcznej na podstawie klucza ciągu.

Ustanawianie rozproszonych usług buforowania

Zarejestruj implementację elementu IDistributedCache w pliku Program.cs. Implementacje dostarczane przez platformę opisane w tym temacie obejmują:

Rozproszona pamięć podręczna Redis Cache

Zalecamy używanie rozproszonej pamięci podręcznej Redis Cache w środowisku produkcyjnym, ponieważ jest to najbardziej wydajne. Aby uzyskać więcej informacji, zobacz Rekomendacje.

Redis to magazyn danych typu open source w pamięci, który jest często używany jako rozproszona pamięć podręczna. Możesz skonfigurować usługę Azure Cache for Redis dla hostowanej na platformie Azure aplikacji ASP.NET Core i użyć usługi Azure Cache for Redis na potrzeby programowania lokalnego.

Aplikacja konfiguruje implementację pamięci podręcznej przy użyciu wystąpienia, wywołując metodę RedisCacheAddStackExchangeRedisCache. W przypadku buforowania danych wyjściowych użyj polecenia AddStackExchangeRedisOutputCache.

  1. Tworzenie usługi Azure Cache for Redis.
  2. Skopiuj parametry połączenia podstawową (StackExchange.Redis) do konfiguracji.
    • Programowanie lokalne: zapisz parametry połączenia za pomocą programu Secret Manager.
    • Azure: zapisz parametry połączenia w konfiguracji usługi App Service lub w innym bezpiecznym magazynie.

Poniższy kod umożliwia korzystanie z usługi Azure Cache for Redis:

builder.Services.AddStackExchangeRedisCache(options =>
 {
     options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
     options.InstanceName = "SampleInstance";
 });

Powyższy kod zakłada, że parametry połączenia primary (StackExchange.Redis) został zapisany w konfiguracji z nazwą MyRedisConStrklucza .

Aby uzyskać więcej informacji, zobacz Pamięć podręczna Azure Cache for Redis.

Zobacz ten problem z usługą GitHub, aby zapoznać się z omówieniem alternatywnych podejść do lokalnej pamięci podręcznej Redis Cache.

Rozproszona pamięć podręczna pamięci

Rozproszona pamięć podręczna (AddDistributedMemoryCache) to implementacja IDistributedCache zapewniana przez platformę, która przechowuje elementy w pamięci. Rozproszona pamięć podręczna nie jest rzeczywistą rozproszoną pamięcią podręczną. Buforowane elementy są przechowywane przez wystąpienie aplikacji na serwerze, na którym działa aplikacja.

Rozproszona pamięć podręczna to przydatna implementacja:

  • W scenariuszach tworzenia i testowania.
  • Jeśli pojedynczy serwer jest używany w środowisku produkcyjnym, a zużycie pamięci nie jest problemem. Implementowanie rozproszonej pamięci podręcznej abstrakcji buforowanego magazynu danych. Umożliwia implementację prawdziwego rozproszonego rozwiązania buforowania w przyszłości, jeśli konieczne będzie zastosowanie wielu węzłów lub odporności na uszkodzenia.

Przykładowa aplikacja korzysta z rozproszonej pamięci podręcznej, gdy aplikacja jest uruchamiana w środowisku programistycznym w Program.csprogramie :

builder.Services.AddDistributedMemoryCache();

Rozproszona pamięć podręczna programu SQL Server

Implementacja rozproszonej pamięci podręcznej programu SQL Server (AddDistributedSqlServerCache) umożliwia rozproszonej pamięci podręcznej używanie bazy danych programu SQL Server jako magazynu zapasowego. Aby utworzyć tabelę elementów buforowanych programu SQL Server w wystąpieniu programu SQL Server, możesz użyć sql-cache tego narzędzia. Narzędzie tworzy tabelę o określonej nazwie i schemacie.

Utwórz tabelę w programie SQL Server, uruchamiając sql-cache create polecenie . Podaj wystąpienie programu SQL Server (), bazę danych (Data SourceInitial Catalog), schemat (na przykład dbo), i nazwę tabeli (na przykład TestCache):

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

Komunikat jest rejestrowany, aby wskazać, że narzędzie zakończyło się pomyślnie:

Table and index were created successfully.

Tabela utworzona sql-cache przez narzędzie ma następujący schemat:

Tabela pamięci podręcznej SqlServer

Uwaga

Aplikacja powinna manipulować wartościami pamięci podręcznej przy użyciu wystąpienia IDistributedCache, a nie .SqlServerCache

Przykładowa aplikacja implementuje SqlServerCache w środowisku nieprogramowania w programie Program.cs:

builder.Services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString(
        "DistCache_ConnectionString");
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

Uwaga

Element ConnectionString (i opcjonalnie SchemaNameTableNamei ) są zwykle przechowywane poza kontrolą źródła (na przykład przechowywane przez menedżera wpisów tajnych lub w appsettings.json/appsettings.{Environment}.json plikach). Parametry połączenia może zawierać poświadczenia, które powinny być przechowywane poza systemami kontroli źródła.

Rozproszona pamięć podręczna NCache

NCache to rozproszona pamięć podręczna typu open source opracowana natywnie na platformie .NET i platformie .NET Core. Usługa NCache działa zarówno lokalnie, jak i skonfigurowana jako rozproszony klaster pamięci podręcznej dla aplikacji ASP.NET Core działającej na platformie Azure lub na innych platformach hostingu.

Aby zainstalować i skonfigurować usługę NCache na komputerze lokalnym, zobacz Wprowadzenie — przewodnik po systemie Windows (.NET i .NET Core)..

Aby skonfigurować usługę NCache:

  1. Zainstaluj pakiet NuGet typu open source NCache.
  2. Skonfiguruj klaster pamięci podręcznej w pliku client.ncconf.
  3. Dodaj następujący kod do pliku Program.cs:
builder.Services.AddNCacheDistributedCache(configuration =>
{
    configuration.CacheName = "democache";
    configuration.EnableLogs = true;
    configuration.ExceptionsEnabled = true;
});

Rozproszona pamięć podręczna usługi Azure CosmosDB

Usługi Azure Cosmos DB można używać w usłudze ASP.NET Core jako dostawcy stanu sesji przy użyciu interfejsu IDistributedCache . Usługa Azure Cosmos DB to w pełni zarządzana baza danych NoSQL i relacyjna baza danych na potrzeby nowoczesnego tworzenia aplikacji, która zapewnia wysoką dostępność, skalowalność i małe opóźnienia dostępu do danych dla aplikacji o znaczeniu krytycznym.

Po zainstalowaniu pliku Microsoft.Extensions.Buforowanie. Pakiet NuGet usługi Cosmos skonfiguruj rozproszoną pamięć podręczną usługi Azure Cosmos DB w następujący sposób:

Ponowne używanie istniejącego klienta

Najprostszym sposobem skonfigurowania rozproszonej pamięci podręcznej jest ponowne użycie istniejącego klienta usługi Azure Cosmos DB. W takim przypadku CosmosClient wystąpienie nie zostanie usunięte po usunięciu dostawcy.

services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
    cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
    cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
    cacheOptions.CosmosClient = existingCosmosClient;
    cacheOptions.CreateIfNotExists = true;
});

Tworzenie nowego klienta

Alternatywnie utwórz wystąpienie nowego klienta. W takim przypadku CosmosClient wystąpienie zostanie usunięte po usunięciu dostawcy.

services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
    cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
    cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
    cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]);
    cacheOptions.CreateIfNotExists = true;
});

Korzystanie z rozproszonej pamięci podręcznej

Aby użyć interfejsu IDistributedCache , zażądaj wystąpienia IDistributedCache w aplikacji. Wystąpienie jest udostępniane przez iniekcję zależności (DI).

Po uruchomieniu IDistributedCache przykładowej aplikacji zostanie wstrzyknięta do Program.cselementu . Bieżący czas jest buforowany przy użyciu IHostApplicationLifetime (aby uzyskać więcej informacji, zobacz Ogólny host: IHostApplicationLifetime):

app.Lifetime.ApplicationStarted.Register(() =>
{
    var currentTimeUTC = DateTime.UtcNow.ToString();
    byte[] encodedCurrentTimeUTC = System.Text.Encoding.UTF8.GetBytes(currentTimeUTC);
    var options = new DistributedCacheEntryOptions()
        .SetSlidingExpiration(TimeSpan.FromSeconds(20));
    app.Services.GetService<IDistributedCache>()
                              .Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
});

Przykładowa aplikacja wprowadza dane IDistributedCache do elementu do IndexModel użycia przez stronę Indeks.

Za każdym razem, gdy strona Indeks jest ładowana, pamięć podręczna jest sprawdzana pod kątem buforowanego czasu w pliku OnGetAsync. Jeśli czas buforowany nie wygasł, zostanie wyświetlony czas. Jeśli 20 sekund upłynęło od czasu ostatniego uzyskania dostępu do pamięci podręcznej (czas ostatniego załadowania tej strony), na stronie zostanie wyświetlony czas wygaśnięcia pamięci podręcznej.

Natychmiast zaktualizuj buforowany czas do bieżącej godziny, wybierając przycisk Resetuj czas buforowany . Przycisk wyzwala metodę OnPostResetCachedTime obsługi.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

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

    public string? CachedTimeUTC { get; set; }
    public string? ASP_Environment { get; set; }

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

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

        ASP_Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        if (String.IsNullOrEmpty(ASP_Environment))
        {
            ASP_Environment = "Null, so Production";
        }
    }

    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();
    }
}

W przypadku IDistributedCache wystąpień z wbudowanymi implementacjami nie trzeba używać okresu istnienia pojedynczego lub zakresu.

Możesz również utworzyć IDistributedCache wystąpienie, w którym może być potrzebne jedno, zamiast użyć di, ale utworzenie wystąpienia w kodzie może utrudnić testowanie kodu i naruszyć zasadę jawnych zależności.

Zalecenia

Podczas podejmowania decyzji o najlepszej implementacji IDistributedCache aplikacji należy wziąć pod uwagę następujące kwestie:

  • Istniejąca infrastruktura
  • Wymagania dotyczące wydajności
  • Koszt
  • Środowisko zespołu

Buforowanie rozwiązania zwykle polegają na magazynie w pamięci, aby zapewnić szybkie pobieranie buforowanych danych, ale pamięć jest ograniczonym zasobem i kosztowna do rozszerzenia. Przechowuj tylko często używane dane w pamięci podręcznej.

W przypadku większości aplikacji pamięć podręczna Redis cache zapewnia większą przepływność i mniejsze opóźnienie niż pamięć podręczna programu SQL Server. Zaleca się jednak przeprowadzenie testów porównawczych w celu określenia cech wydajności strategii buforowania.

Gdy program SQL Server jest używany jako magazyn kopii zapasowych rozproszonej pamięci podręcznej, użycie tej samej bazy danych dla pamięci podręcznej i zwykłego magazynu danych i pobierania aplikacji może negatywnie wpłynąć na wydajność obu tych elementów. Zalecamy użycie dedykowanego wystąpienia programu SQL Server dla magazynu kopii zapasowych rozproszonej pamięci podręcznej.

Dodatkowe zasoby

Rozproszona pamięć podręczna to pamięć podręczna współużytkowana przez wiele serwerów aplikacji, zwykle utrzymywana jako usługa zewnętrzna dla serwerów aplikacji, które uzyskują do niej dostęp. Rozproszona pamięć podręczna może zwiększyć wydajność i skalowalność aplikacji ASP.NET Core, zwłaszcza gdy aplikacja jest hostowana przez usługę w chmurze lub farmę serwerów.

Rozproszona pamięć podręczna ma kilka zalet w przypadku innych scenariuszy buforowania, w których buforowane dane są przechowywane na poszczególnych serwerach aplikacji.

Gdy buforowane dane są dystrybuowane, dane:

  • Jest spójna (spójna ) między żądaniami na wielu serwerach.
  • Przetrwa ponowne uruchomienie serwera i wdrożenia aplikacji.
  • Nie używa pamięci lokalnej.

Konfiguracja rozproszonej pamięci podręcznej jest specyficzna dla implementacji. W tym artykule opisano sposób konfigurowania rozproszonych pamięci podręcznych sql Server i Redis. Dostępne są również implementacje innych firm, takie jak NCache (NCache w usłudze GitHub). Niezależnie od wybranej implementacji aplikacja współdziała z pamięcią podręczną przy użyciu interfejsu IDistributedCache .

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

Dodaj odwołanie do pakietu dla używanego dostawcy rozproszonej pamięci podręcznej:

IDistributedCache, interfejs

Interfejs IDistributedCache udostępnia następujące metody manipulowania elementami w implementacji rozproszonej pamięci podręcznej:

  • Get, GetAsync: akceptuje klucz ciągu i pobiera buforowany element jako tablicę byte[] , jeśli zostanie znaleziony w pamięci podręcznej.
  • Set, SetAsync: dodaje element (jako byte[] tablicę) do pamięci podręcznej przy użyciu klucza ciągu.
  • Refresh, RefreshAsync: odświeża element w pamięci podręcznej na podstawie jego klucza, resetując jego przesuwany limit czasu wygaśnięcia (jeśli istnieje).
  • Remove, RemoveAsync: usuwa element pamięci podręcznej na podstawie klucza ciągu.

Ustanawianie rozproszonych usług buforowania

Zarejestruj implementację elementu IDistributedCache w pliku Program.cs. Implementacje dostarczane przez platformę opisane w tym temacie obejmują:

Rozproszona pamięć podręczna Redis Cache

Zalecamy używanie rozproszonej pamięci podręcznej Redis Cache w środowisku produkcyjnym, ponieważ jest to najbardziej wydajne. Aby uzyskać więcej informacji, zobacz Rekomendacje.

Redis to magazyn danych typu open source w pamięci, który jest często używany jako rozproszona pamięć podręczna. Możesz skonfigurować pamięć podręczną Azure Redis Cache dla hostowanej na platformie Azure aplikacji ASP.NET Core i użyć usługi Azure Redis Cache na potrzeby programowania lokalnego.

Aplikacja konfiguruje implementację pamięci podręcznej RedisCache przy użyciu wystąpienia (AddStackExchangeRedisCache).

  1. Tworzenie usługi Azure Cache for Redis.
  2. Skopiuj parametry połączenia podstawową (StackExchange.Redis) do konfiguracji.
    • Programowanie lokalne: zapisz parametry połączenia za pomocą programu Secret Manager.
    • Azure: zapisz parametry połączenia w konfiguracji usługi App Service lub w innym bezpiecznym magazynie.

Poniższy kod umożliwia korzystanie z usługi Azure Cache for Redis:

builder.Services.AddStackExchangeRedisCache(options =>
 {
     options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
     options.InstanceName = "SampleInstance";
 });

Powyższy kod zakłada, że parametry połączenia primary (StackExchange.Redis) został zapisany w konfiguracji z nazwą MyRedisConStrklucza .

Aby uzyskać więcej informacji, zobacz Pamięć podręczna Azure Cache for Redis.

Zobacz ten problem z usługą GitHub, aby zapoznać się z omówieniem alternatywnych podejść do lokalnej pamięci podręcznej Redis Cache.

Rozproszona pamięć podręczna pamięci

Rozproszona pamięć podręczna (AddDistributedMemoryCache) to implementacja IDistributedCache zapewniana przez platformę, która przechowuje elementy w pamięci. Rozproszona pamięć podręczna nie jest rzeczywistą rozproszoną pamięcią podręczną. Buforowane elementy są przechowywane przez wystąpienie aplikacji na serwerze, na którym działa aplikacja.

Rozproszona pamięć podręczna to przydatna implementacja:

  • W scenariuszach tworzenia i testowania.
  • Jeśli pojedynczy serwer jest używany w środowisku produkcyjnym, a zużycie pamięci nie jest problemem. Implementowanie rozproszonej pamięci podręcznej abstrakcji buforowanego magazynu danych. Umożliwia implementację prawdziwego rozproszonego rozwiązania buforowania w przyszłości, jeśli konieczne będzie zastosowanie wielu węzłów lub odporności na uszkodzenia.

Przykładowa aplikacja korzysta z rozproszonej pamięci podręcznej, gdy aplikacja jest uruchamiana w środowisku programistycznym w Program.csprogramie :

builder.Services.AddDistributedMemoryCache();

Rozproszona pamięć podręczna programu SQL Server

Implementacja rozproszonej pamięci podręcznej programu SQL Server (AddDistributedSqlServerCache) umożliwia rozproszonej pamięci podręcznej używanie bazy danych programu SQL Server jako magazynu zapasowego. Aby utworzyć tabelę elementów buforowanych programu SQL Server w wystąpieniu programu SQL Server, możesz użyć sql-cache tego narzędzia. Narzędzie tworzy tabelę o określonej nazwie i schemacie.

Utwórz tabelę w programie SQL Server, uruchamiając sql-cache create polecenie . Podaj wystąpienie programu SQL Server (), bazę danych (Data SourceInitial Catalog), schemat (na przykład dbo), i nazwę tabeli (na przykład TestCache):

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

Komunikat jest rejestrowany, aby wskazać, że narzędzie zakończyło się pomyślnie:

Table and index were created successfully.

Tabela utworzona sql-cache przez narzędzie ma następujący schemat:

Tabela pamięci podręcznej SqlServer

Uwaga

Aplikacja powinna manipulować wartościami pamięci podręcznej przy użyciu wystąpienia IDistributedCache, a nie .SqlServerCache

Przykładowa aplikacja implementuje SqlServerCache w środowisku nieprogramowania w programie Program.cs:

builder.Services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString(
        "DistCache_ConnectionString");
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

Uwaga

Element ConnectionString (i opcjonalnie SchemaNameTableNamei ) są zwykle przechowywane poza kontrolą źródła (na przykład przechowywane przez menedżera wpisów tajnych lub w appsettings.json/appsettings.{Environment}.json plikach). Parametry połączenia może zawierać poświadczenia, które powinny być przechowywane poza systemami kontroli źródła.

Rozproszona pamięć podręczna NCache

NCache to rozproszona pamięć podręczna typu open source opracowana natywnie na platformie .NET i platformie .NET Core. Usługa NCache działa zarówno lokalnie, jak i skonfigurowana jako rozproszony klaster pamięci podręcznej dla aplikacji ASP.NET Core działającej na platformie Azure lub na innych platformach hostingu.

Aby zainstalować i skonfigurować usługę NCache na komputerze lokalnym, zobacz Wprowadzenie — przewodnik po systemie Windows (.NET i .NET Core)..

Aby skonfigurować usługę NCache:

  1. Zainstaluj pakiet NuGet typu open source NCache.
  2. Skonfiguruj klaster pamięci podręcznej w pliku client.ncconf.
  3. Dodaj następujący kod do pliku Program.cs:
builder.Services.AddNCacheDistributedCache(configuration =>
{
    configuration.CacheName = "democache";
    configuration.EnableLogs = true;
    configuration.ExceptionsEnabled = true;
});

Korzystanie z rozproszonej pamięci podręcznej

Aby użyć interfejsu IDistributedCache , zażądaj wystąpienia IDistributedCache w aplikacji. Wystąpienie jest udostępniane przez iniekcję zależności (DI).

Po uruchomieniu IDistributedCache przykładowej aplikacji zostanie wstrzyknięta do Program.cselementu . Bieżący czas jest buforowany przy użyciu IHostApplicationLifetime (aby uzyskać więcej informacji, zobacz Ogólny host: IHostApplicationLifetime):

app.Lifetime.ApplicationStarted.Register(() =>
{
    var currentTimeUTC = DateTime.UtcNow.ToString();
    byte[] encodedCurrentTimeUTC = System.Text.Encoding.UTF8.GetBytes(currentTimeUTC);
    var options = new DistributedCacheEntryOptions()
        .SetSlidingExpiration(TimeSpan.FromSeconds(20));
    app.Services.GetService<IDistributedCache>()
                              .Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
});

Przykładowa aplikacja wprowadza dane IDistributedCache do elementu do IndexModel użycia przez stronę Indeks.

Za każdym razem, gdy strona Indeks jest ładowana, pamięć podręczna jest sprawdzana pod kątem buforowanego czasu w pliku OnGetAsync. Jeśli czas buforowany nie wygasł, zostanie wyświetlony czas. Jeśli 20 sekund upłynęło od czasu ostatniego uzyskania dostępu do pamięci podręcznej (czas ostatniego załadowania tej strony), na stronie zostanie wyświetlony czas wygaśnięcia pamięci podręcznej.

Natychmiast zaktualizuj buforowany czas do bieżącej godziny, wybierając przycisk Resetuj czas buforowany . Przycisk wyzwala metodę OnPostResetCachedTime obsługi.

public class IndexModel : PageModel
{
    private readonly IDistributedCache _cache;

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

    public string? CachedTimeUTC { get; set; }
    public string? ASP_Environment { get; set; }

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

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

        ASP_Environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        if (String.IsNullOrEmpty(ASP_Environment))
        {
            ASP_Environment = "Null, so Production";
        }
    }

    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();
    }
}

W przypadku IDistributedCache wystąpień z wbudowanymi implementacjami nie trzeba używać okresu istnienia pojedynczego lub zakresu.

Możesz również utworzyć IDistributedCache wystąpienie, w którym może być potrzebne jedno, zamiast użyć di, ale utworzenie wystąpienia w kodzie może utrudnić testowanie kodu i naruszyć zasadę jawnych zależności.

Zalecenia

Podczas podejmowania decyzji o najlepszej implementacji IDistributedCache aplikacji należy wziąć pod uwagę następujące kwestie:

  • Istniejąca infrastruktura
  • Wymagania dotyczące wydajności
  • Koszt
  • Środowisko zespołu

Buforowanie rozwiązania zwykle polegają na magazynie w pamięci, aby zapewnić szybkie pobieranie buforowanych danych, ale pamięć jest ograniczonym zasobem i kosztowna do rozszerzenia. Przechowuj tylko często używane dane w pamięci podręcznej.

W przypadku większości aplikacji pamięć podręczna Redis cache zapewnia większą przepływność i mniejsze opóźnienie niż pamięć podręczna programu SQL Server. Zaleca się jednak przeprowadzenie testów porównawczych w celu określenia cech wydajności strategii buforowania.

Gdy program SQL Server jest używany jako magazyn kopii zapasowych rozproszonej pamięci podręcznej, użycie tej samej bazy danych dla pamięci podręcznej i zwykłego magazynu danych i pobierania aplikacji może negatywnie wpłynąć na wydajność obu tych elementów. Zalecamy użycie dedykowanego wystąpienia programu SQL Server dla magazynu kopii zapasowych rozproszonej pamięci podręcznej.

Dodatkowe zasoby

Rozproszona pamięć podręczna to pamięć podręczna współużytkowana przez wiele serwerów aplikacji, zwykle utrzymywana jako usługa zewnętrzna dla serwerów aplikacji, które uzyskują do niej dostęp. Rozproszona pamięć podręczna może zwiększyć wydajność i skalowalność aplikacji ASP.NET Core, zwłaszcza gdy aplikacja jest hostowana przez usługę w chmurze lub farmę serwerów.

Rozproszona pamięć podręczna ma kilka zalet w przypadku innych scenariuszy buforowania, w których buforowane dane są przechowywane na poszczególnych serwerach aplikacji.

Gdy buforowane dane są dystrybuowane, dane:

  • Jest spójna (spójna ) między żądaniami na wielu serwerach.
  • Przetrwa ponowne uruchomienie serwera i wdrożenia aplikacji.
  • Nie używa pamięci lokalnej.

Konfiguracja rozproszonej pamięci podręcznej jest specyficzna dla implementacji. W tym artykule opisano sposób konfigurowania rozproszonych pamięci podręcznych sql Server i Redis. Dostępne są również implementacje innych firm, takie jak NCache (NCache w usłudze GitHub). Niezależnie od wybranej implementacji aplikacja współdziała z pamięcią podręczną przy użyciu interfejsu IDistributedCache .

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

Aby użyć rozproszonej pamięci podręcznej programu SQL Server, dodaj odwołanie do pakietu do pliku Microsoft.Extensions.Buforowanie. Pakiet SqlServer.

Aby użyć rozproszonej pamięci podręcznej Redis, dodaj odwołanie do pakietu do pliku Microsoft.Extensions.Buforowanie. Pakiet StackExchangeRedis.

Aby użyć rozproszonej pamięci podręcznej NCache, dodaj odwołanie do pakietu NCache.Microsoft.Extensions.Buforowanie. Pakiet OpenSource.

IDistributedCache, interfejs

Interfejs IDistributedCache udostępnia następujące metody manipulowania elementami w implementacji rozproszonej pamięci podręcznej:

  • Get, GetAsync: akceptuje klucz ciągu i pobiera buforowany element jako tablicę byte[] , jeśli zostanie znaleziony w pamięci podręcznej.
  • Set, SetAsync: dodaje element (jako byte[] tablicę) do pamięci podręcznej przy użyciu klucza ciągu.
  • Refresh, RefreshAsync: odświeża element w pamięci podręcznej na podstawie jego klucza, resetując jego przesuwany limit czasu wygaśnięcia (jeśli istnieje).
  • Remove, RemoveAsync: usuwa element pamięci podręcznej na podstawie klucza ciągu.

Ustanawianie rozproszonych usług buforowania

Zarejestruj implementację elementu IDistributedCache w pliku Startup.ConfigureServices. Implementacje dostarczane przez platformę opisane w tym temacie obejmują:

Rozproszona pamięć podręczna pamięci

Rozproszona pamięć podręczna (AddDistributedMemoryCache) to implementacja IDistributedCache zapewniana przez platformę, która przechowuje elementy w pamięci. Rozproszona pamięć podręczna nie jest rzeczywistą rozproszoną pamięcią podręczną. Buforowane elementy są przechowywane przez wystąpienie aplikacji na serwerze, na którym działa aplikacja.

Rozproszona pamięć podręczna to przydatna implementacja:

  • W scenariuszach tworzenia i testowania.
  • Jeśli pojedynczy serwer jest używany w środowisku produkcyjnym, a zużycie pamięci nie jest problemem. Implementowanie rozproszonej pamięci podręcznej abstrakcji buforowanego magazynu danych. Umożliwia implementację prawdziwego rozproszonego rozwiązania buforowania w przyszłości, jeśli konieczne będzie zastosowanie wielu węzłów lub odporności na uszkodzenia.

Przykładowa aplikacja korzysta z rozproszonej pamięci podręcznej, gdy aplikacja jest uruchamiana w środowisku programistycznym w Startup.ConfigureServicesprogramie :

services.AddDistributedMemoryCache();

Rozproszona pamięć podręczna programu SQL Server

Implementacja rozproszonej pamięci podręcznej programu SQL Server (AddDistributedSqlServerCache) umożliwia rozproszonej pamięci podręcznej używanie bazy danych programu SQL Server jako magazynu zapasowego. Aby utworzyć tabelę elementów buforowanych programu SQL Server w wystąpieniu programu SQL Server, możesz użyć sql-cache tego narzędzia. Narzędzie tworzy tabelę o określonej nazwie i schemacie.

Utwórz tabelę w programie SQL Server, uruchamiając sql-cache create polecenie . Podaj wystąpienie programu SQL Server (), bazę danych (Data SourceInitial Catalog), schemat (na przykład dbo), i nazwę tabeli (na przykład TestCache):

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

Komunikat jest rejestrowany, aby wskazać, że narzędzie zakończyło się pomyślnie:

Table and index were created successfully.

Tabela utworzona sql-cache przez narzędzie ma następujący schemat:

Tabela pamięci podręcznej SqlServer

Uwaga

Aplikacja powinna manipulować wartościami pamięci podręcznej przy użyciu wystąpienia IDistributedCache, a nie .SqlServerCache

Przykładowa aplikacja implementuje SqlServerCache w środowisku nieprogramowania w programie Startup.ConfigureServices:

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

Uwaga

Element ConnectionString (i opcjonalnie SchemaNameTableNamei ) są zwykle przechowywane poza kontrolą źródła (na przykład przechowywane przez menedżera wpisów tajnych lub w appsettings.json/appsettings.{Environment}.json plikach). Parametry połączenia może zawierać poświadczenia, które powinny być przechowywane poza systemami kontroli źródła.

Rozproszona pamięć podręczna Redis Cache

Redis to magazyn danych typu open source w pamięci, który jest często używany jako rozproszona pamięć podręczna. Możesz skonfigurować pamięć podręczną Azure Redis Cache dla hostowanej na platformie Azure aplikacji ASP.NET Core i użyć usługi Azure Redis Cache na potrzeby programowania lokalnego.

Aplikacja konfiguruje implementację pamięci podręcznej RedisCache przy użyciu wystąpienia (AddStackExchangeRedisCache).

  1. Tworzenie usługi Azure Cache for Redis.
  2. Skopiuj parametry połączenia podstawową (StackExchange.Redis) do konfiguracji.
    • Programowanie lokalne: zapisz parametry połączenia za pomocą programu Secret Manager.
    • Azure: zapisz parametry połączenia w konfiguracji usługi App Service lub w innym bezpiecznym magazynie.

Poniższy kod umożliwia korzystanie z usługi 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();
}

Powyższy kod zakłada, że parametry połączenia primary (StackExchange.Redis) został zapisany w konfiguracji z nazwą MyRedisConStrklucza .

Aby uzyskać więcej informacji, zobacz Pamięć podręczna Azure Cache for Redis.

Zobacz ten problem z usługą GitHub, aby zapoznać się z omówieniem alternatywnych podejść do lokalnej pamięci podręcznej Redis Cache.

Rozproszona pamięć podręczna NCache

NCache to rozproszona pamięć podręczna typu open source opracowana natywnie na platformie .NET i platformie .NET Core. Usługa NCache działa zarówno lokalnie, jak i skonfigurowana jako rozproszony klaster pamięci podręcznej dla aplikacji ASP.NET Core działającej na platformie Azure lub na innych platformach hostingu.

Aby zainstalować i skonfigurować usługę NCache na komputerze lokalnym, zobacz Wprowadzenie — przewodnik po systemie Windows (.NET i .NET Core)..

Aby skonfigurować usługę NCache:

  1. Zainstaluj pakiet NuGet typu open source NCache.

  2. Skonfiguruj klaster pamięci podręcznej w pliku client.ncconf.

  3. Dodaj następujący kod do pliku Startup.ConfigureServices:

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

Korzystanie z rozproszonej pamięci podręcznej

Aby użyć interfejsu IDistributedCache , zażądaj wystąpienia IDistributedCache z dowolnego konstruktora w aplikacji. Wystąpienie jest udostępniane przez iniekcję zależności (DI).

Po uruchomieniu IDistributedCache przykładowej aplikacji zostanie wstrzyknięta do Startup.Configureelementu . Bieżący czas jest buforowany przy użyciu IHostApplicationLifetime (aby uzyskać więcej informacji, zobacz Ogólny host: 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);
    });

Przykładowa aplikacja wprowadza dane IDistributedCache do elementu do IndexModel użycia przez stronę Indeks.

Za każdym razem, gdy strona Indeks jest ładowana, pamięć podręczna jest sprawdzana pod kątem buforowanego czasu w pliku OnGetAsync. Jeśli czas buforowany nie wygasł, zostanie wyświetlony czas. Jeśli 20 sekund upłynęło od czasu ostatniego uzyskania dostępu do pamięci podręcznej (czas ostatniego załadowania tej strony), na stronie zostanie wyświetlony czas wygaśnięcia pamięci podręcznej.

Natychmiast zaktualizuj buforowany czas do bieżącej godziny, wybierając przycisk Resetuj czas buforowany . Przycisk wyzwala metodę OnPostResetCachedTime obsługi.

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();
    }
}

Uwaga

Nie ma potrzeby używania okresu istnienia pojedynczego lub zakresu dla IDistributedCache wystąpień (co najmniej w przypadku wbudowanych implementacji).

Możesz również utworzyć IDistributedCache wystąpienie, w którym może być potrzebne jedno, zamiast użyć di, ale utworzenie wystąpienia w kodzie może utrudnić testowanie kodu i naruszyć zasadę jawnych zależności.

Zalecenia

Podczas podejmowania decyzji o najlepszej implementacji IDistributedCache aplikacji należy wziąć pod uwagę następujące kwestie:

  • Istniejąca infrastruktura
  • Wymagania dotyczące wydajności
  • Koszt
  • Środowisko zespołu

Buforowanie rozwiązania zwykle polegają na magazynie w pamięci, aby zapewnić szybkie pobieranie buforowanych danych, ale pamięć jest ograniczonym zasobem i kosztowna do rozszerzenia. Przechowuj tylko często używane dane w pamięci podręcznej.

Ogólnie rzecz biorąc, pamięć podręczna Redis cache zapewnia większą przepływność i mniejsze opóźnienie niż pamięć podręczna programu SQL Server. Jednak testy porównawcze są zwykle wymagane do określenia cech wydajności strategii buforowania.

Gdy program SQL Server jest używany jako magazyn kopii zapasowych rozproszonej pamięci podręcznej, użycie tej samej bazy danych dla pamięci podręcznej i zwykłego magazynu danych i pobierania aplikacji może negatywnie wpłynąć na wydajność obu tych elementów. Zalecamy użycie dedykowanego wystąpienia programu SQL Server dla magazynu kopii zapasowych rozproszonej pamięci podręcznej.

Dodatkowe zasoby