Sdílet prostřednictvím


Knihovna HybridCache v ASP.NET Core

Důležité

HybridCache v současné době je stále ve verzi Preview, ale bude plně vydána po .NET 9.0 v budoucí dílčí verzi rozšíření .NET.

Tento článek vysvětluje, jak nakonfigurovat a používat knihovnu HybridCache v aplikaci ASP.NET Core. Úvod do knihovny najdete v HybridCache části Přehled ukládání do mezipaměti.

Získání knihovny

Nainstalujte balíček Microsoft.Extensions.Caching.Hybrid.

dotnet add package Microsoft.Extensions.Caching.Hybrid --version "9.0.0-preview.7.24406.2"

Registrace služby

HybridCache Přidejte službu do kontejneru injektáž závislostí (DI) volánímAddHybridCache:

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

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

builder.Services.AddHybridCache();

Předchozí kód zaregistruje HybridCache službu s výchozími možnostmi. Rozhraní API pro registraci může také konfigurovat možnosti a serializaci.

Získání a uložení položek mezipaměti

Služba HybridCache poskytuje metodu GetOrCreateAsync se dvěma přetíženími, přičemž přebírá klíč a:

  • Metoda továrny.
  • Stav a metoda továrny

Metoda používá klíč k pokusu o načtení objektu z primární mezipaměti. Pokud se položka v primární mezipaměti nenajde (chybí mezipaměť), zkontroluje sekundární mezipaměť, pokud je nakonfigurovaná. Pokud tam nenajde data (jiná zmeškaná mezipaměť), zavolá metodu továrny, která získá objekt ze zdroje dat. Pak uloží objekt do primární i sekundární mezipaměti. Metoda továrny se nikdy nevolá, pokud se objekt nachází v primární nebo sekundární mezipaměti (přístup do mezipaměti).

Služba HybridCache zajišťuje, že pro daný klíč volá metodu továrny pouze jeden souběžný volající a všichni ostatní volající čekají na výsledek tohoto volání. GetOrCreateAsync Předání CancellationToken představuje kombinované zrušení všech souběžných volajících.

GetOrCreateAsync Hlavní přetížení

Pro většinu scénářů se doporučuje bezstavové přetížení GetOrCreateAsync . Kód, který ho má volat, je relativně jednoduchý. Tady je příklad:

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),
            cancellationToken: token
        );
    }

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

GetOrCreateAsync Alternativní přetížení

Alternativní přetížení může snížit některé režijní náklady z zachycených proměnných a zpětných volání na instanci, ale na úkor složitějšího kódu. U většiny scénářů zvýšení výkonu nepřeváží složitost kódu. Tady je příklad, který používá alternativní přetížení:

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),
            cancellationToken: token
        );
    }

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

Metoda SetAsync

V mnoha scénářích GetOrCreateAsync je jediné potřebné rozhraní API. Kromě toho HybridCache musí SetAsync objekt uložit do mezipaměti, aniž byste se ho nejdřív pokusili načíst.

Odebrání položek mezipaměti podle klíče

Když se podkladová data pro položku mezipaměti před vypršením platnosti změní, odeberte ji explicitně voláním RemoveAsync klíče k položce. Přetížení umožňuje zadat kolekci hodnot klíčů.

Když je položka odebrána, odebere se z primární i sekundární mezipaměti.

Odebrání položek mezipaměti podle značky

Značky lze použít k seskupení položek mezipaměti a jejich zneplatnění.

Nastavte značky při volání GetOrCreateAsync, jak je znázorněno v následujícím příkladu:

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,
            cancellationToken: token
        );
    }
    
    public async Task<string> GetDataFromTheSourceAsync(string name, int id, CancellationToken token)
    {
        string someInfo = $"someinfo-{name}-{id}";
        return someInfo;
    }
}

Odeberte všechny položky pro zadanou značku voláním RemoveByTagAsync hodnoty značky. Přetížení umožňuje zadat kolekci hodnot značek.

Když je položka odebrána, odebere se z primární i sekundární mezipaměti.

Možnosti

Metodu AddHybridCache lze použít ke konfiguraci globálních výchozích hodnot. Následující příklad ukazuje, jak nakonfigurovat některé z dostupných možností:

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

Metoda GetOrCreateAsync může také přepsat HybridCacheEntryOptions objekt, který přepíše globální výchozí hodnoty pro určitou položku mezipaměti. Tady je příklad:

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,
            cancellationToken: token
        );
    }
    
    public async Task<string> GetDataFromTheSourceAsync(string name, int id, CancellationToken token)
    {
        string someInfo = $"someinfo-{name}-{id}";
        return someInfo;
    }
}

Další informace o možnostech najdete ve zdrojovém kódu:

Omezení

Následující vlastnosti HybridCacheOptions umožňují konfigurovat limity, které platí pro všechny položky mezipaměti:

  • MaximumPayloadBytes – maximální velikost položky mezipaměti. Výchozí hodnota je 1 MB. Zaprotokolují se pokusy o uložení hodnot nad touto velikostí a hodnota není uložená v mezipaměti.
  • MaximumKeyLength – maximální délka klíče mezipaměti. Výchozí hodnota je 1024 znaků. Zaprotokolují se pokusy o uložení hodnot nad touto velikostí a hodnota není uložená v mezipaměti.

Serializace

Použití sekundární mezipaměti mimo proces vyžaduje serializaci. Serializace se konfiguruje jako součást registrace HybridCache služby. Serializátory specifické pro konkrétní typ a obecné účely lze konfigurovat prostřednictvím AddSerializer metod a AddSerializerFactory zřetězených AddHybridCache z volání. Ve výchozím nastavení knihovna zpracovává string a byte[] interně a používá System.Text.Json se pro všechno ostatní. HybridCache může také používat jiné serializátory, jako je protobuf nebo XML.

Následující příklad nakonfiguruje službu tak, aby používala serializátor protobuf specifický pro typ:

// 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)
        };
    }).AddSerializer<SomeProtobufMessage, 
        GoogleProtobufSerializer<SomeProtobufMessage>>();

Následující příklad nakonfiguruje službu tak, aby používala serializátor protobuf pro obecné účely, který dokáže zpracovat mnoho typů 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)
    };
}).AddSerializerFactory<GoogleProtobufSerializerFactory>();

Sekundární mezipaměť vyžaduje úložiště dat, jako je Redis nebo SqlServer. Použití služby Azure Cache for Redis, například:

  • Nainstalujte balíček Microsoft.Extensions.Caching.StackExchangeRedis.

  • Vytvořte instanci Azure Cache for Redis.

  • Získejte připojovací řetězec, který se připojuje k instanci Redis. Vyhledejte připojovací řetězec tak, že na stránce Přehled na webu Azure Portal vyberete Zobrazit přístupové klíče.

  • Uložte připojovací řetězec v konfiguraci aplikace. Například použijte soubor tajných kódů uživatele, který vypadá jako následující JSON, s připojovací řetězec v ConnectionStrings části. Nahraďte <the connection string> skutečným připojovací řetězec:

    {
      "ConnectionStrings": {
        "RedisConnectionString": "<the connection string>"
      }
    }
    
  • Zaregistrujte se v di implementaci IDistributedCache , kterou balíček Redis poskytuje. Uděláte to tak, že zavoláte AddStackExchangeRedisCachea předáte připojovací řetězec. Příklad:

    builder.Services.AddStackExchangeRedisCache(options =>
    {
        options.Configuration = 
            builder.Configuration.GetConnectionString("RedisConnectionString");
    });
    
  • Implementace Redis IDistributedCache je teď dostupná z kontejneru DI aplikace. HybridCache používá ho jako sekundární mezipaměť a používá pro ni serializátor nakonfigurovaný.

Další informace naleznete v ukázkové aplikaci serializace HybridCache.

Ukládání do mezipaměti

Ve výchozím nastavení HybridCache se používá MemoryCache pro primární úložiště mezipaměti. Položky mezipaměti se ukládají v procesu, takže každý server má samostatnou mezipaměť, která se ztratí při každém restartování procesu serveru. Pro sekundární mimoprocesové úložiště, jako je Redis nebo SQL Server, HybridCache používá nakonfigurovanou IDistributedCache implementaci( pokud existuje). I bez IDistributedCacheimplementace HybridCache ale služba stále zajišťuje ukládání do mezipaměti v procesu a ochranu s razítkem.

Optimalizace výkonu

Pokud chcete optimalizovat výkon, nakonfigurujte HybridCache opakované použití objektů a vyhněte se byte[] přidělení.

Opakované použití objektů

Opětovným použitím instancí HybridCache může snížit režii přidělení procesoru a objektů spojených s deserializací podle volání. To může vést ke zlepšení výkonu ve scénářích, kdy jsou objekty uložené v mezipaměti velké nebo často přístupné.

V typickém existujícím kódu, který používá IDistributedCache, každé načtení objektu z mezipaměti má za následek deserializaci. Toto chování znamená, že každý souběžný volající získá samostatnou instanci objektu, která nemůže komunikovat s jinými instancemi. Výsledkem je bezpečnost vláken, protože neexistuje riziko souběžných úprav stejné instance objektu.

Vzhledem k tomu, že se mnoho HybridCache využití přizpůsobí existujícímu IDistributedCache kódu, zachová toto chování ve výchozím nastavení, HybridCache aby nedocházelo k chybám souběžnosti. Objekty jsou však ze své podstaty bezpečné pro přístup z více vláken, pokud:

  • Jedná se o neměnné typy.
  • Kód je nezmění.

V takových případech informujte HybridCache , že je bezpečné opakovaně používat instance pomocí:

  • Označení typu jako sealed. Klíčové sealed slovo v jazyce C# znamená, že třídu nelze dědit.
  • Použití atributu [ImmutableObject(true)] na typ. Atribut [ImmutableObject(true)] označuje, že stav objektu nelze po vytvoření změnit.

Vyhněte se byte[] přidělením

HybridCache poskytuje také volitelná rozhraní API pro IDistributedCache implementace, aby se zabránilo byte[] přidělení. Tuto funkci implementují verze Microsoft.Extensions.Caching.StackExchangeRedis Preview a Microsoft.Extensions.Caching.SqlServer balíčky. Další informace najdete v tématu IBufferDistributedCache Tady jsou příkazy rozhraní příkazového řádku .NET pro instalaci balíčků:

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

Vlastní implementace HybridCache

Konkrétní implementace HybridCache abstraktní třídy je zahrnuta ve sdílené architektuře a je poskytována prostřednictvím injektáže závislostí. Vývojáři ale můžou poskytovat vlastní implementace rozhraní API.

Kompatibilita

Knihovna HybridCache podporuje starší moduly runtime .NET až .NET Framework 4.7.2 a .NET Standard 2.0.

Další materiály

Další informace o HybridCachenástroji najdete v následujících zdrojích informací: