Biblioteka hybridCache w programie ASP.NET Core
Ważne
HybridCache
jest obecnie nadal dostępna w wersji zapoznawczej, ale zostanie w pełni wydana po wersji .NET 9.0 w przyszłej wersji pomocniczej rozszerzeń platformy .NET.
W tym artykule wyjaśniono, jak skonfigurować bibliotekę HybridCache
i używać jej w aplikacji ASP.NET Core. Aby zapoznać się z wprowadzeniem do biblioteki, zobacz HybridCache
sekcję Omówienie buforowania.
Pobieranie biblioteki
Zainstaluj pakiet Microsoft.Extensions.Caching.Hybrid
.
dotnet add package Microsoft.Extensions.Caching.Hybrid --version "9.0.0-preview.7.24406.2"
Rejestrowanie usługi
Dodaj usługę HybridCache
do kontenera wstrzykiwania zależności (DI), wywołując polecenie AddHybridCache
:
// Add services to the container.
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthorization();
builder.Services.AddHybridCache();
Powyższy kod rejestruje usługę HybridCache
przy użyciu opcji domyślnych. Interfejs API rejestracji może również skonfigurować opcje i serializacji.
Pobieranie i przechowywanie wpisów pamięci podręcznej
Usługa HybridCache
udostępnia metodę z dwoma GetOrCreateAsync
przeciążeniami, przyjmując klucz i:
- Metoda fabryki.
- Stan i metoda fabryki.
Metoda używa klucza, aby spróbować pobrać obiekt z podstawowej pamięci podręcznej. Jeśli element nie zostanie znaleziony w podstawowej pamięci podręcznej (brakuje pamięci podręcznej), sprawdza pomocniczą pamięć podręczną, jeśli została skonfigurowana. Jeśli nie znajdzie tam danych (inna miss pamięci podręcznej), wywołuje metodę fabryki, aby pobrać obiekt ze źródła danych. Następnie przechowuje obiekt w pamięciach podręcznych podstawowych i pomocniczych. Metoda fabryki nigdy nie jest wywoływana, jeśli obiekt znajduje się w podstawowej lub pomocniczej pamięci podręcznej (trafieniu pamięci podręcznej).
HybridCache
Usługa zapewnia, że tylko jeden współbieżny obiekt wywołujący dla danego klucza wywołuje metodę fabryki, a wszystkie inne wywołujące czekają na wynik tego wywołania. Przekazany element CancellationToken
reprezentuje GetOrCreateAsync
połączone anulowanie wszystkich współbieżnych wywołań.
Główne GetOrCreateAsync
przeciążenie
Przeciążenie bezstanowe GetOrCreateAsync
polecenia jest zalecane w przypadku większości scenariuszy. Kod do wywołania jest stosunkowo prosty. Oto przykład:
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;
}
}
Alternatywne GetOrCreateAsync
przeciążenie
Alternatywne przeciążenie może zmniejszyć obciążenie związane z przechwyconymi zmiennymi i wywołaniami zwrotnymi dla poszczególnych wystąpień, ale kosztem bardziej złożonego kodu. W większości scenariuszy wzrost wydajności nie przewyższa złożoności kodu. Oto przykład, który używa alternatywnego przeciążenia:
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
W wielu scenariuszach GetOrCreateAsync
jest jedynym wymaganym interfejsem API. Ale HybridCache
musi SetAsync
również przechowywać obiekt w pamięci podręcznej bez próby pobrania go najpierw.
Usuwanie wpisów pamięci podręcznej według klucza
Gdy dane bazowe dla wpisu pamięci podręcznej zmienią się przed jego wygaśnięciem, usuń wpis jawnie, wywołując RemoveAsync
klucz do wpisu. Przeciążenie umożliwia określenie kolekcji wartości kluczy.
Po usunięciu wpisu zostanie on usunięty zarówno z pamięci podręcznej podstawowej, jak i pomocniczej.
Usuwanie wpisów pamięci podręcznej według tagu
Tagi mogą służyć do grupowania wpisów pamięci podręcznej i unieważniać je razem.
Ustaw tagi podczas wywoływania metody GetOrCreateAsync
, jak pokazano w poniższym przykładzie:
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;
}
}
Usuń wszystkie wpisy dla określonego tagu, wywołując RemoveByTagAsync
element z wartością tagu. Przeciążenie umożliwia określenie kolekcji wartości tagów.
Po usunięciu wpisu zostanie on usunięty zarówno z pamięci podręcznej podstawowej, jak i pomocniczej.
Opcje
Metody AddHybridCache
można użyć do skonfigurowania wartości domyślnych globalnych. W poniższym przykładzie pokazano, jak skonfigurować niektóre z dostępnych opcji:
// 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
może również przesłonić HybridCacheEntryOptions
globalne wartości domyślne dla określonego wpisu pamięci podręcznej. Oto przykład:
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;
}
}
Aby uzyskać więcej informacji na temat opcji, zobacz kod źródłowy:
- HybridCacheOptions, klasa.
- HybridCacheEntryOptions, klasa.
Limity
Następujące właściwości HybridCacheOptions
umożliwiają skonfigurowanie limitów, które mają zastosowanie do wszystkich wpisów pamięci podręcznej:
- MaximumPayloadBytes — maksymalny rozmiar wpisu pamięci podręcznej. Wartość domyślna to 1 MB. Próby przechowywania wartości w tym rozmiarze są rejestrowane, a wartość nie jest przechowywana w pamięci podręcznej.
- MaximumKeyLength — maksymalna długość klucza pamięci podręcznej. Wartość domyślna to 1024 znaki. Próby przechowywania wartości w tym rozmiarze są rejestrowane, a wartość nie jest przechowywana w pamięci podręcznej.
Serializacja
Użycie pomocniczej pamięci podręcznej poza procesem wymaga serializacji. Serializacja jest konfigurowana w ramach rejestrowania HybridCache
usługi. Serializatory specyficzne dla typu i ogólnego przeznaczenia można skonfigurować za pośrednictwem AddSerializer
metod i AddSerializerFactory
, w łańcuchu od wywołania AddHybridCache
. Domyślnie biblioteka obsługuje string
i byte[]
wewnętrznie używa System.Text.Json
wszystkich innych elementów. HybridCache
może również używać innych serializatorów, takich jak protobuf lub XML.
Poniższy przykład konfiguruje usługę tak, aby korzystała z serializatora protobuf specyficznego dla typu:
// 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>>();
Poniższy przykład konfiguruje usługę tak, aby korzystała z serializatora protobuf ogólnego przeznaczenia, który może obsługiwać wiele typów 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>();
Pomocnicza pamięć podręczna wymaga magazynu danych, takiego jak Redis lub SqlServer. Aby użyć usługi Azure Cache for Redis, na przykład:
Zainstaluj pakiet
Microsoft.Extensions.Caching.StackExchangeRedis
.Utwórz wystąpienie usługi Azure Cache for Redis.
Pobierz parametry połączenia, który łączy się z wystąpieniem usługi Redis. Znajdź parametry połączenia, wybierając pozycję Pokaż klucze dostępu na stronie Przegląd w witrynie Azure Portal.
Zapisz parametry połączenia w konfiguracji aplikacji. Na przykład użyj pliku wpisów tajnych użytkownika, który wygląda podobnie do poniższego kodu JSON z parametry połączenia w
ConnectionStrings
sekcji . Zastąp<the connection string>
element rzeczywistym parametry połączenia:{ "ConnectionStrings": { "RedisConnectionString": "<the connection string>" } }
Zarejestruj się w di implementacji
IDistributedCache
dostarczanej przez pakiet Redis. Aby to zrobić, wywołaj metodęAddStackExchangeRedisCache
i przekaż parametry połączenia. Na przykład:builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = builder.Configuration.GetConnectionString("RedisConnectionString"); });
Implementacja usługi Redis
IDistributedCache
jest teraz dostępna z kontenera DI aplikacji.HybridCache
używa go jako pomocniczej pamięci podręcznej i używa serializatora skonfigurowanego dla niego.
Aby uzyskać więcej informacji, zobacz przykładową aplikację serializacji hybridcache.
Magazyn pamięci podręcznej
Domyślnie HybridCache
jest używany MemoryCache dla jego podstawowego magazynu pamięci podręcznej. Wpisy pamięci podręcznej są przechowywane w procesie, dlatego każdy serwer ma oddzielną pamięć podręczną, która zostanie utracona przy każdym ponownym uruchomieniu procesu serwera. W przypadku pomocniczego magazynu poza procesem, takiego jak Redis lub SQL Server, HybridCache
używa skonfigurowanej IDistributedCache
implementacji, jeśli istnieje. Ale nawet bez IDistributedCache
implementacji HybridCache
usługa nadal zapewnia buforowanie procesów i ochronę stampede.
Optymalizowanie wydajności
Aby zoptymalizować wydajność, skonfiguruj do HybridCache
ponownego użycia obiektów i unikaj byte[]
alokacji.
Ponowne używanie obiektów
Przez ponowne użycie wystąpień HybridCache
może zmniejszyć obciążenie związane z alokacją procesora CPU i obiektu skojarzonymi z deserializacji poszczególnych wywołań. Może to prowadzić do poprawy wydajności w scenariuszach, w których buforowane obiekty są duże lub często używane.
W typowym istniejącym kodzie, który używa IDistributedCache
metody , każde pobieranie obiektu z pamięci podręcznej powoduje deserializacji. To zachowanie oznacza, że każdy współbieżny obiekt wywołujący pobiera oddzielne wystąpienie obiektu, które nie może wchodzić w interakcje z innymi wystąpieniami. Wynikiem jest bezpieczeństwo wątków, ponieważ nie ma ryzyka współbieżnych modyfikacji w tym samym wystąpieniu obiektu.
Ponieważ wiele HybridCache
użycia zostanie dostosowanych z istniejącego IDistributedCache
kodu, zachowuje to zachowanie domyślnie, HybridCache
aby uniknąć wprowadzania usterek współbieżności. Jednak obiekty są z natury bezpieczne wątkowo, jeśli:
- Są to niezmienne typy.
- Kod nie modyfikuje ich.
W takich przypadkach należy poinformować HybridCache
, że ponowne użycie wystąpień jest bezpieczne przez:
- Oznaczanie typu jako
sealed
. Słowosealed
kluczowe w języku C# oznacza, że nie można dziedziczyć klasy. - Stosowanie atrybutu
[ImmutableObject(true)]
do typu. Atrybut[ImmutableObject(true)]
wskazuje, że nie można zmienić stanu obiektu po jego utworzeniu.
Unikaj byte[]
alokacji
HybridCache
Udostępnia również opcjonalne interfejsy API dla IDistributedCache
implementacji, aby uniknąć byte[]
alokacji. Ta funkcja jest implementowana przez wersje Microsoft.Extensions.Caching.StackExchangeRedis
zapoznawcza pakietów i Microsoft.Extensions.Caching.SqlServer
. Aby uzyskać więcej informacji, zobacz IBufferDistributedCache Oto polecenia interfejsu wiersza polecenia platformy .NET służące do instalowania pakietów:
dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis --prerelease
dotnet add package Microsoft.Extensions.Caching.SqlServer --prerelease
Niestandardowe implementacje usługi HybridCache
Konkretna implementacja klasy abstrakcyjnej HybridCache
jest zawarta w strukturze udostępnionej i jest dostarczana za pośrednictwem wstrzykiwania zależności. Deweloperzy są jednak mile widziani, aby zapewnić niestandardowe implementacje interfejsu API.
Zgodność
Biblioteka HybridCache
obsługuje starsze środowiska uruchomieniowe platformy .NET w dół do programów .NET Framework 4.7.2 i .NET Standard 2.0.
Dodatkowe zasoby
Aby uzyskać więcej informacji na temat HybridCache
programu , zobacz następujące zasoby: