Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek vysvětluje, jak nakonfigurovat a používat knihovnu HybridCache v aplikaci ASP.NET Core. Úvod do knihovny najdete v části HybridCache Přehled ukládání do mezipaměti.
Získejte knihovnu
Nainstalujte balíček Microsoft.Extensions.Caching.Hybrid.
dotnet add package Microsoft.Extensions.Caching.Hybrid
Registrace služby
Přidejte službu HybridCache do kontejneru vkládání závislostí (DI) voláním AddHybridCache:
// 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řijímá klíč a:
- Tovární metoda.
- 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 (další neúspěšný pokus v mezipaměti), zavolá tovární metodu pro získání objektu 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 (zásah 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í. Parametr CancellationToken předaný do GetOrCreateAsync představuje celkové zrušení všech souběžných volajících.
GetOrCreateAsync Hlavní přetížení
Pro většinu scénářů se doporučuje použít bezstavové přetížení GetOrCreateAsync. Kód k jeho volání 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;
}
}
Pokyny pro klíče mezipaměti
key, který je předán do GetOrCreateAsync, musí jedinečně identifikovat data, která se ukládají do mezipaměti.
- Pokud jde o hodnoty identifikátoru použité k načtení těchto dat z jeho zdroje.
- Z hlediska jiných dat uložených v mezipaměti v aplikaci.
Oba typy jedinečnosti se obvykle zajišťují pomocí řetězení řetězců, aby se vytvořil jediný klíčový řetězec složený z různých částí spojených do jednoho řetězce. Příklad:
cache.GetOrCreateAsync($"/orders/{region}/{orderId}", ...);
Nebo
cache.GetOrCreateAsync($"user_prefs_{userId}", ...);
Je zodpovědností volajícího zajistit, aby bylo schéma klíčů platné a nemohlo způsobit zmatení dat.
Nepoužívejte vstup externího uživatele přímo v klíčích mezipaměti. Nepoužívejte například nezpracované řetězce z uživatelských rozhraní jako klíče mezipaměti. Tím můžete aplikaci vystavit rizikům zabezpečení, jako je neoprávněný přístup nebo útoky na dostupnost služby způsobené zahltit mezipamětí náhodnými nebo bezvýznamnými klíči. V předchozích platných příkladech jsou data o objednávkách a uživatelských preferencích jasně oddělena a používají důvěryhodné identifikátory.
-
orderidauserIdjsou interně generované identifikátory. -
regionmůže být výčtem nebo řetězcem z předdefinovaného seznamu známých oblastí.
Žádný význam není přikládán tokenům, jako jsou / nebo _. Celá hodnota klíče je považována za neprůznačný řetězec. V tomto případě byste mohli vynechat / a _ beze změny způsobu fungování mezipaměti, ale oddělovač se obvykle používá k zabránění nejednoznačnosti – například $"order{customerId}{orderId}" může způsobit nejasnost mezi:
-
customerId42 sorderId123 -
customerId421 seorderId23
Oba předchozí příklady by vygenerovaly klíč order42123mezipaměti .
Tyto pokyny platí stejně pro všechna rozhraní API mezipaměti založená na string, jako jsou HybridCache, IDistributedCachea IMemoryCache.
Všimněte si, že syntaxe vloženého interpolovaného řetězce ($"..." v dříve uvedených příkladech platných klíčů) se nachází přímo ve volání GetOrCreateAsync. Tato syntaxe se doporučuje při použití HybridCache, protože umožňuje plánovaná budoucí vylepšení, která obcházejí potřebu přidělit string pro klíč v mnoha scénářích.
Další klíčové aspekty
- Klíče mohou být omezeny na platné maximální délky. Výchozí implementace
HybridCache(prostřednictvímAddHybridCache(...)) například ve výchozím nastavení omezuje klíče na 1024 znaků. Toto číslo je možné konfigurovat prostřednictvímHybridCacheOptions.MaximumKeyLength, přičemž delší klíče obcházejí mechanismy mezipaměti, aby se zabránilo jejich přeplnění. - Klíče musí být platné sekvence Unicode. Pokud jsou předány neplatné sekvence Unicode, chování není definováno.
- Při použití sekundární mezipaměti mimo proces, jako je například
IDistributedCache, může implementace backendu zavádět další omezení. Jako hypotetický příklad může konkrétní back-end používat logiku klíče bez rozlišování malých a velkých písmen. Ve výchozím nastaveníHybridCache(prostřednictvímAddHybridCache(...)) se tento scénář detekuje, aby se zabránilo záměnným útokům nebo útokům aliasů (pomocí rovnosti bitového řetězce). Nicméně tento scénář může stále způsobit, že konfliktní klíče budou přepsány nebo odstraněny dříve, než se očekávalo.
GetOrCreateAsync Alternativní přetížení funkcí
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 jednotlivé instance, ale na úkor složitějšího kódu. Ve většině 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 je rozhraní API GetOrCreateAsync tím jediným, které je potřeba. 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 klíčových hodnot.
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 zavoláním RemoveByTagAsync s hodnotou značky. Přetížení umožňuje zadat kolekci hodnot tagů.
Ani IMemoryCache nemá přímou podporu pro koncept značek, takže zneplatnění založené na značkách je IDistributedCache operace. Aktivně neodebere hodnoty z místní nebo distribuované mezipaměti. Místo toho zajišťuje, že při příjmu dat s těmito značkami jsou data považována za chybějící v místní i vzdálené mezipaměti. Platnost hodnot vyprší z IMemoryCache a IDistributedCache obvyklým způsobem na základě nakonfigurované životnosti.
Odebrání všech položek mezipaměti
Hvězdička (*) je vyhrazena jako zástupný znak a je zakázána pro jednotlivé hodnoty. Volání RemoveByTagAsync("*") má vliv na zneplatnění všechHybridCache dat, a to i dat, která nemají žádné značky. Stejně jako u jednotlivých značek se jedná o logickou operaci a jednotlivé hodnoty nadále existují, dokud jejich platnost nevyprší přirozeně. Shody ve stylu globu nejsou podporovány. Nemůžete například použít RemoveByTagAsync("foo*") k odebrání všeho, co začíná foo.
Další úvahy o značkách
- Systém neomezuje počet značek, které můžete použít, ale velké sady značek můžou negativně ovlivnit výkon.
- Značky nemůžou být prázdné, pouze mezery nebo rezervovaná hodnota
*.
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řijmout 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:
- třída HybridCacheOptions
- třída HybridCacheEntryOptions
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 i pro obecné účely lze konfigurovat pomocí metod AddSerializer a AddSerializerFactory, které jsou zřetězené z volání AddHybridCache. Ve výchozím nastavení knihovna zpracovává string a byte[] interně a používá System.Text.Json 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, SQL Server nebo Postgres. 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 pro připojení 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 uživatelských tajemství, který vypadá jako následující JSON, s připojovacím řetězcem v části
ConnectionStrings. Nahraďte<the connection string>skutečným připojovacím řetězcem.{ "ConnectionStrings": { "RedisConnectionString": "<the connection string>" } }Zaregistrujte v DI implementaci
IDistributedCache, kterou poskytuje balíček Redis. Uděláte to tak, že zavoláteAddStackExchangeRedisCachea předáte připojovací řetězec. Příklad:builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = builder.Configuration.GetConnectionString("RedisConnectionString"); });Implementace Redis
IDistributedCacheje teď dostupná z kontejneru DI aplikace.HybridCachepouží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, SQL Server nebo Postgres, HybridCache používá nakonfigurovanou IDistributedCache implementaci ( pokud existuje). I bez implementace IDistributedCache služba HybridCache ale stále poskytuje ukládání do mezipaměti v procesu a ochranu proti lavinovému efektu.
Poznámka
Při zneplatnění položek mezipaměti podle klíče nebo značek se zneplatní na aktuálním serveru a v sekundárním úložišti mimo proces. Mezipaměť v paměti na jiných serverech však není ovlivněna.
Optimalizace výkonu
Pokud chcete optimalizovat výkon, nakonfigurujte HybridCache, aby opakoval použití objektů a vyhněte se byte[] alokacím.
Opakované použití objektů
Opětovným použitím instancí může HybridCache snížit režii alokace CPU a objektů spojenou s deserializací při každém 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 mnoho HybridCache využití bude přizpůsobeno stávajícímu IDistributedCache kódu, HybridCache zachovává toto chování ve výchozím nastavení, aby nedocházelo k problémům se souběžností. Objekty jsou však ze své podstaty zabezpečené 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 provedením obou následujících změn:
- Označení typu jako
sealed. Klíčovésealedslovo 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ělování
HybridCache také poskytuje volitelná rozhraní API pro implementace IDistributedCache, čímž se vyhne přidělování byte[]. Tato funkce je implementována předběžnými verzemi balíčků Microsoft.Extensions.Caching.StackExchangeRedis, Microsoft.Extensions.Caching.SqlServer a Microsoft.Extensions.Caching.Postgres. 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
dotnet add package Microsoft.Extensions.Caching.SqlServer
dotnet add package Microsoft.Extensions.Caching.Postgres
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 mohou poskytovat nebo využívat vlastní implementace rozhraní API, například FusionCache.
Použijte hybridní mezipaměť s nativní AOT
Následující aspekty specifické pro nativní AOT platí pro HybridCache:
serializace
Nativní AOT nepodporuje serializaci založenou na reflexi modulu runtime. Pokud ukládáte vlastní typy do mezipaměti, musíte použít generátory zdrojů nebo explicitně nakonfigurovat serializátory, které jsou kompatibilní s AOT, jako generování zdroje pomocí
System.Text.Json.HybridCacheje stále ve vývoji, a zjednodušení způsobu, jak ho používat s AOT, je pro tento vývoj vysokou prioritou. Další informace najdete v pull requestu dotnet/extensions#6475.Zastřihávání
Ujistěte se, že všechny typy, které ukládáte do cache, jsou odkazovány způsobem, který zabrání jejich oříznutí kompilátorem AOT. Použití generátorů zdrojů pro serializaci pomáhá s tímto požadavkem. Další informace najdete v tématu ASP.NET Podpora jádra pro nativní AOT.
Pokud nastavíte serializaci a oříznete správně, HybridCache chová se v nativní AOT stejně jako v běžných aplikacích ASP.NET Core.
Kompatibilita
Knihovna HybridCache podporuje starší vlastnosti runtime .NET až do .NET Framework 4.7.2 a .NET Standard 2.0.
Další materiály
Další informace najdete ve zdrojovém HybridCache kódu.