Verteiltes Zwischenspeichern in ASP.NET Core
Von Mohsin Nasir und smandia
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Ein verteilter Cache ist ein Cache, der von mehreren App-Servern gemeinsam genutzt wird und in der Regel als externer Dienst für die App-Server verwaltet wird, die darauf zugreifen. Ein verteilter Cache kann die Leistung und Skalierbarkeit einer ASP.NET Core-App verbessern, insbesondere wenn die App von einem Clouddienst oder einer Serverfarm gehostet wird.
Ein verteilter Cache hat mehrere Vorteile gegenüber anderen Zwischenspeicherungsszenarien, in denen zwischengespeicherte Daten auf einzelnen App-Servern gespeichert werden.
Wenn zwischengespeicherte Daten verteilt werden, gilt für sie Folgendes:
- Sie sind kohärent (konsistent) für Anforderungen an mehrere Server.
- Sie überleben Serverneustarts und App-Bereitstellungen.
- Sie verwenden keinen lokalen Arbeitsspeicher.
Die Konfiguration des verteilten Cache ist implementierungsspezifisch. In diesem Artikel wird beschrieben, wie Sie verteilte Caches von SQL Server und Redis konfigurieren. Drittanbieterimplementierungen sind ebenfalls verfügbar, z. B. NCache (NCache auf GitHub). Unabhängig davon, welche Implementierung ausgewählt ist, interagiert die App über die Schnittstelle IDistributedCache mit dem Cache.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Warnung
In diesem Artikel wird eine lokale Datenbank verwendet, für die keine Authentifizierung des Benutzers erforderlich ist. Produktions-Apps sollten den sichersten verfügbaren Ablauf für die Authentifizierung verwenden. Weitere Informationen zur Authentifizierung für bereitgestellte Test- und Produktions-Apps finden Sie unter Sichere Authentifizierungsflows.
Voraussetzungen
Fügen Sie einen Paketverweis für den verwendeten verteilten Cacheanbieter hinzu:
- Für einen verteilten Redis-Cache Microsoft.Extensions.Caching.StackExchangeRedis.
- Für SQL Server Microsoft.Extensions.Caching.SqlServer.
- Für den verteilten NCache-Cache NCache.Microsoft.Extensions.Caching.OpenSource.
IDistributedCache-Schnittstelle
Die IDistributedCache-Schnittstelle bietet die folgenden Methoden zum Bearbeiten von Elementen bei der Implementierung des verteilten Cache:
- Get, GetAsync: Akzeptiert einen Zeichenfolgenschlüssel und ruft ein zwischengespeichertes Element als
byte[]
-Array ab, wenn es im Cache gefunden wird. - Set, SetAsync: Fügt dem Cache mithilfe eines Zeichenfolgenschlüssels ein Element (als
byte[]
-Array) hinzu. - Refresh, RefreshAsync: Aktualisiert ein Element im Cache auf Grundlage seines Schlüssels und setzt das gleitende Ablauftimeout (sofern vorhanden) zurück.
- Remove, RemoveAsync: Entfernt ein Cacheelement anhand seines Zeichenfolgenschlüssels.
Einrichten verteilter Zwischenspeicherdienste
Registrieren Sie eine Implementierung von IDistributedCache in Program.cs
. Im Framework bereitgestellte Implementierungen, die in diesem Thema beschrieben werden, umfassen:
- Verteilter Redis-Cache
- Verteilter Speichercache
- Verteilter SQL Server-Cache
- Verteilter NCache-Cache
- Verteilter Azure CosmosDB Cache
Verteilter Redis-Cache
Es wird empfohlen, dass Produktions-Apps den verteilten Redis-Cache verwenden, da er am leistungsfähigsten ist. Weitere Informationen finden Sie unter Empfehlungen.
Redis ist ein Open Source In-Memory-Datenspeicher, der häufig als verteilter Cache verwendet wird. Sie können eine Azure Cache for Redis-Instanz für eine von Azure gehostete ASP.NET Core-App konfigurieren und eine Azure Cache for Redis-Instanz für die lokale Entwicklung verwenden.
Eine App konfiguriert die Cacheimplementierung mithilfe einer RedisCache-Instanz durch Aufrufen von AddStackExchangeRedisCache. Für die Ausgabezwischenspeicherung verwenden Sie AddStackExchangeRedisOutputCache
.
- Erstellen Sie einen Azure Cache for Redis.
- Kopieren Sie die primäre Verbindungszeichenfolge (StackExchange.Redis) in Configuration.
- Lokale Entwicklung: Speichern Sie die Verbindungszeichenfolge mit Secret Manager.
- Azure: Speichern der Verbindungszeichenfolge in einem sicheren Speicher wie Azure Key Vault
Der folgende Code aktiviert Azure Cache for Redis:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
options.InstanceName = "SampleInstance";
});
Im vorherigen Code wird davon ausgegangen, dass die primäre Verbindungszeichenfolge (StackExchange.Redis) in Configuration mit dem Schlüsselnamen MyRedisConStr
gespeichert wurde.
Weitere Informationen finden Sie unter Azure Cache for Redis.
In diesem GitHub-Problem finden Sie eine Diskussion zu alternativen Ansätzen für einen lokalen Redis-Cache.
Verteilter Speichercache
Der verteilte Speichercache (AddDistributedMemoryCache) ist eine vom Framework bereitgestellte Implementierung von IDistributedCache, die Elemente im Arbeitsspeicher speichert. Der verteilte Speichercache ist kein tatsächlich verteilter Cache. Zwischengespeicherte Elemente werden von der App-Instanz auf dem Server gespeichert, auf dem die App ausgeführt wird.
Der verteilte Speichercache ist eine nützliche Implementierung:
- In Entwicklungs- und Testszenarien.
- Wenn ein einzelner Server in der Produktion verwendet wird und die Arbeitsspeichernutzung kein Problem ist. Durch die Implementierung des verteilten Speichercache wird die Speicherung von Cachedaten abstrahiert. Dies ermöglicht die Implementierung einer echten verteilten Zwischenspeicherungslösung in der Zukunft, wenn mehrere Knoten oder Fehlertoleranz erforderlich werden.
Die Beispiel-App verwendet den verteilten Speichercache, wenn die App in der Entwicklungsumgebung in Program.cs
ausgeführt wird:
builder.Services.AddDistributedMemoryCache();
Verteilter SQL Server-Cache
Die Implementierung des verteilten SQL Server-Cache (AddDistributedSqlServerCache) ermöglicht es dem verteilten Cache, eine SQL Server-Datenbank als Sicherungsspeicher zu verwenden. Um eine zwischengespeicherte SQL Server.Elementtabelle in einer SQL Server-Instanz zu erstellen, können Sie das Tool sql-cache
verwenden. Das Tool erstellt eine Tabelle mit dem von Ihnen angegebenen Namen und Schema.
Erstellen Sie eine Tabelle in SQL Server, indem Sie den Befehl sql-cache create
ausführen. Geben Sie die SQL Server-Instanz (Data Source
), die Datenbank (Initial Catalog
), das Schema (z. B. dbo
) und den Tabellennamen (z. B. TestCache
) an:
dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
Eine Meldung wird protokolliert, um anzugeben, dass das Tool erfolgreich war:
Table and index were created successfully.
Die vom sql-cache
-Tool erstellte Tabelle weist das folgende Schema auf:
Hinweis
Eine App sollte Cachewerte mithilfe einer Instanz von IDistributedCache, nicht von SqlServerCache, bearbeiten.
Die Beispiel-App implementiert SqlServerCache in einer Nicht-Entwicklungsumgebung in Program.cs
:
builder.Services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString(
"DistCache_ConnectionString");
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Hinweis
ConnectionString sowie optional SchemaName und TableName werden in der Regel außerhalb der Quellcodeverwaltung gespeichert (z. B. vom Secret Manager oder in appsettings.json
/appsettings.{Environment}.json
-Dateien gespeichert). Die Verbindungszeichenfolge kann Anmeldeinformationen enthalten, die außerhalb der Quellcodeverwaltungssysteme aufbewahrt werden sollten.
Verteilter NCache-Cache
NCache ist ein verteilter Open Source In-Memory-Cache, der nativ in .NET und .NET Core entwickelt wurde. NCache funktioniert sowohl lokal als auch als verteilter Cachecluster für eine ASP.NET Core-App, die in Azure oder auf anderen Hostingplattformen ausgeführt wird.
Informationen zum Installieren und Konfigurieren von NCache auf Ihrem lokalen Computer finden Sie unter Leitfaden mit ersten Schritten für Windows (.NET und .NET Core).
So konfigurieren Sie NCache:
- Installieren Sie NCache Open Source NuGet.
- Konfigurieren Sie den Cachecluster in client.ncconf.
- Fügen Sie den folgenden Code zu
Program.cs
hinzu:
builder.Services.AddNCacheDistributedCache(configuration =>
{
configuration.CacheName = "democache";
configuration.EnableLogs = true;
configuration.ExceptionsEnabled = true;
});
Verteilter Azure CosmosDB Cache
Azure Cosmos DB kann in ASP.NET Core als Sitzungszustandsanbieter mithilfe der IDistributedCache
-Schnittstelle verwendet werden. Azure Cosmos DB ist eine vollständig verwaltete NoSQL- und relationale Datenbank für die moderne Anwendungsentwicklung, die hohe Verfügbarkeit, Skalierbarkeit und Zugriff auf Daten mit geringer Latenz für unternehmenskritische Anwendungen bietet.
Konfigurieren Sie nach der Installation des Microsoft.Extensions.Caching.Cosmos NuGet-Pakets einen verteilten Azure Cosmos DB-Cache wie folgt:
Wiederverwenden eines vorhandenen Clients
Die einfachste Möglichkeit zum Konfigurieren des verteilten Caches besteht darin, einen vorhandenen Azure Cosmos DB-Client erneut zu verwenden. In diesem Fall wird die CosmosClient
-Instanz nicht verworfen, wenn der Anbieter verworfen wird.
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
cacheOptions.CosmosClient = existingCosmosClient;
cacheOptions.CreateIfNotExists = true;
});
Erstellen eines neuen Clients
Alternativ können Sie einen neuen Client instanziieren. In diesem Fall wird die CosmosClient
-Instanz gelöscht, wenn der Anbieter verworfen wird.
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]);
cacheOptions.CreateIfNotExists = true;
});
Verwenden des verteilten Cache
Um die IDistributedCache-Schnittstelle zu verwenden, fordern Sie eine Instanz von IDistributedCache in der App an. Die Instanz wird durch Abhängigkeitsinjektion (Dependency Injection, DI) bereitgestellt.
Wenn die Beispiel-App gestartet wird, wird IDistributedCache in Program.cs
eingebracht. Die aktuelle Zeit wird mit IHostApplicationLifetime zwischengespeichert (weitere Informationen finden Sie unter Generischer 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);
});
Die Beispiel-App bringt IDistributedCache zwecks Verwendung durch die Indexseite in IndexModel
ein.
Jedes Mal, wenn die Indexseite geladen wird, wird der Cache auf die zwischengespeicherte Zeit in OnGetAsync
überprüft. Wenn die zwischengespeicherte Zeit nicht abgelaufen ist, wird die Uhrzeit angezeigt. Wenn seit dem letzten Zugriff auf die zwischengespeicherte Zeit (das letzte Laden dieser Seite) 20 Sekunden verstrichen sind, wird auf der Seite Zwischengespeicherte Zeit abgelaufen angezeigt.
Aktualisieren Sie sofort die zwischengespeicherte Zeit auf die aktuelle Zeit, indem Sie die Schaltfläche Zwischengespeicherte Zeit zurücksetzen auswählen. Die Schaltfläche löst die Handlermethode OnPostResetCachedTime
aus.
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();
}
}
Es ist nicht erforderlich, eine Singleton- oder bereichsbezogene Lebensdauer für IDistributedCache-Instanzen mit den integrierten Implementierungen zu verwenden.
Sie können zudem eine IDistributedCache-Instanz überall dort erstellen, wo Sie anstelle von DI eine Instanz benötigen, aber das Erstellen einer Instanz im Code kann das Testen Ihres Codes erschweren und gegen das Prinzip der expliziten Abhängigkeiten verstoßen.
Empfehlungen
Bei der Entscheidung, welche Implementierung von IDistributedCache für Ihre App am besten geeignet ist, sollten Sie Folgendes berücksichtigen:
- Vorhandene Infrastruktur
- Leistungsanforderungen
- Kosten
- Teamerfahrung
Zwischenspeicherlösungen basieren in der Regel auf In-Memory-Speicher, um einen schnellen Abruf von zwischengespeicherten Daten zu ermöglichen. Der Arbeitsspeicher ist jedoch nur eine begrenzte Ressource und seine Erweiterung kostspielig. Speichern Sie nur häufig verwendete Daten in einem Cache.
Für die meisten Apps bietet ein Redis-Cache einen höheren Durchsatz und eine geringere Latenz als ein SQL Server-Cache. Es wird jedoch ein Benchmarking empfohlen, um die Leistungsmerkmale von Zwischenspeicherungsstrategien zu bestimmen.
Wenn SQL Server als verteilter Cachesicherungsspeicher verwendet wird, kann sich die Verwendung derselben Datenbank für den Cache und die normale Datenspeicherung der App und das Abrufen negativ auf die Leistung beider auswirken. Es wird empfohlen, eine dedizierte SQL Server-Instanz für den verteilten Cachesicherungsspeicher zu verwenden.
Zusätzliche Ressourcen
- Redis Cache in Azure
- SQL-Datenbank in Azure
- ASP.NET Core IDistributedCache-Anbieter für NCache in Webfarmen (NCache in GitHub)
- Repository README-Datei für Microsoft.Extensions.Caching.Cosmos
- Zwischenspeichern im Arbeitsspeicher in ASP.NET Core
- Erkennen von Änderungen mit Änderungstoken in ASP.NET Core
- Zwischenspeichern von Antworten in ASP.NET Core
- Middleware für das Zwischenspeichern von Antworten in ASP.NET Core
- Cache-Taghilfsprogramm im ASP.NET Core MVC
- Taghilfsprogramm für verteilten Cache in ASP.NET Core
- Hosten von ASP.NET Core in einer Webfarm
Ein verteilter Cache ist ein Cache, der von mehreren App-Servern gemeinsam genutzt wird und in der Regel als externer Dienst für die App-Server verwaltet wird, die darauf zugreifen. Ein verteilter Cache kann die Leistung und Skalierbarkeit einer ASP.NET Core-App verbessern, insbesondere wenn die App von einem Clouddienst oder einer Serverfarm gehostet wird.
Ein verteilter Cache hat mehrere Vorteile gegenüber anderen Zwischenspeicherungsszenarien, in denen zwischengespeicherte Daten auf einzelnen App-Servern gespeichert werden.
Wenn zwischengespeicherte Daten verteilt werden, gilt für sie Folgendes:
- Sie sind kohärent (konsistent) für Anforderungen an mehrere Server.
- Sie überleben Serverneustarts und App-Bereitstellungen.
- Sie verwenden keinen lokalen Arbeitsspeicher.
Die Konfiguration des verteilten Cache ist implementierungsspezifisch. In diesem Artikel wird beschrieben, wie Sie verteilte Caches von SQL Server und Redis konfigurieren. Drittanbieterimplementierungen sind ebenfalls verfügbar, z. B. NCache (NCache auf GitHub). Unabhängig davon, welche Implementierung ausgewählt ist, interagiert die App über die Schnittstelle IDistributedCache mit dem Cache.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Voraussetzungen
Fügen Sie einen Paketverweis für den verwendeten verteilten Cacheanbieter hinzu:
Für einen verteilten Redis-Cache Microsoft.Extensions.Caching.StackExchangeRedis.
Für SQL Server Microsoft.Extensions.Caching.SqlServer.
Für den verteilten NCache-Cache NCache.Microsoft.Extensions.Caching.OpenSource.
-
Warnung
In diesem Artikel wird eine lokale Datenbank verwendet, für die keine Authentifizierung des Benutzers erforderlich ist. Produktions-Apps sollten den sichersten verfügbaren Ablauf für die Authentifizierung verwenden. Weitere Informationen zur Authentifizierung für bereitgestellte Test- und Produktions-Apps finden Sie unter Sichere Authentifizierungsflows.
IDistributedCache-Schnittstelle
Die IDistributedCache-Schnittstelle bietet die folgenden Methoden zum Bearbeiten von Elementen bei der Implementierung des verteilten Cache:
- Get, GetAsync: Akzeptiert einen Zeichenfolgenschlüssel und ruft ein zwischengespeichertes Element als
byte[]
-Array ab, wenn es im Cache gefunden wird. - Set, SetAsync: Fügt dem Cache mithilfe eines Zeichenfolgenschlüssels ein Element (als
byte[]
-Array) hinzu. - Refresh, RefreshAsync: Aktualisiert ein Element im Cache auf Grundlage seines Schlüssels und setzt das gleitende Ablauftimeout (sofern vorhanden) zurück.
- Remove, RemoveAsync: Entfernt ein Cacheelement anhand seines Zeichenfolgenschlüssels.
Einrichten verteilter Zwischenspeicherdienste
Registrieren Sie eine Implementierung von IDistributedCache in Program.cs
. Im Framework bereitgestellte Implementierungen, die in diesem Thema beschrieben werden, umfassen:
Verteilter Redis-Cache
Es wird empfohlen, dass Produktions-Apps den verteilten Redis-Cache verwenden, da er am leistungsfähigsten ist. Weitere Informationen finden Sie unter Empfehlungen.
Redis ist ein Open Source In-Memory-Datenspeicher, der häufig als verteilter Cache verwendet wird. Sie können einen Azure Redis Cache für eine von Azure gehostete ASP.NET Core-App konfigurieren und einen Azure Redis Cache für die lokale Entwicklung verwenden.
Eine App konfiguriert die Cacheimplementierung mithilfe einer RedisCache-Instanz (AddStackExchangeRedisCache).
- Erstellen Sie einen Azure Cache for Redis.
- Kopieren Sie die primäre Verbindungszeichenfolge (StackExchange.Redis) in Configuration.
- Lokale Entwicklung: Speichern Sie die Verbindungszeichenfolge mit Secret Manager.
- Azure: Speichern der Verbindungszeichenfolge in einem sicheren Speicher wie Azure Key Vault
Der folgende Code aktiviert Azure Cache for Redis:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
options.InstanceName = "SampleInstance";
});
Im vorherigen Code wird davon ausgegangen, dass die primäre Verbindungszeichenfolge (StackExchange.Redis) in Configuration mit dem Schlüsselnamen MyRedisConStr
gespeichert wurde.
Weitere Informationen finden Sie unter Azure Cache for Redis.
In diesem GitHub-Problem finden Sie eine Diskussion zu alternativen Ansätzen für einen lokalen Redis-Cache.
Verteilter Speichercache
Der verteilte Speichercache (AddDistributedMemoryCache) ist eine vom Framework bereitgestellte Implementierung von IDistributedCache, die Elemente im Arbeitsspeicher speichert. Der verteilte Speichercache ist kein tatsächlich verteilter Cache. Zwischengespeicherte Elemente werden von der App-Instanz auf dem Server gespeichert, auf dem die App ausgeführt wird.
Der verteilte Speichercache ist eine nützliche Implementierung:
- In Entwicklungs- und Testszenarien.
- Wenn ein einzelner Server in der Produktion verwendet wird und die Arbeitsspeichernutzung kein Problem ist. Durch die Implementierung des verteilten Speichercache wird die Speicherung von Cachedaten abstrahiert. Dies ermöglicht die Implementierung einer echten verteilten Zwischenspeicherungslösung in der Zukunft, wenn mehrere Knoten oder Fehlertoleranz erforderlich werden.
Die Beispiel-App verwendet den verteilten Speichercache, wenn die App in der Entwicklungsumgebung in Program.cs
ausgeführt wird:
builder.Services.AddDistributedMemoryCache();
Verteilter SQL Server-Cache
Die Implementierung des verteilten SQL Server-Cache (AddDistributedSqlServerCache) ermöglicht es dem verteilten Cache, eine SQL Server-Datenbank als Sicherungsspeicher zu verwenden. Um eine zwischengespeicherte SQL Server.Elementtabelle in einer SQL Server-Instanz zu erstellen, können Sie das Tool sql-cache
verwenden. Das Tool erstellt eine Tabelle mit dem von Ihnen angegebenen Namen und Schema.
Erstellen Sie eine Tabelle in SQL Server, indem Sie den Befehl sql-cache create
ausführen. Geben Sie die SQL Server-Instanz (Data Source
), die Datenbank (Initial Catalog
), das Schema (z. B. dbo
) und den Tabellennamen (z. B. TestCache
) an:
dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
Eine Meldung wird protokolliert, um anzugeben, dass das Tool erfolgreich war:
Table and index were created successfully.
Die vom sql-cache
-Tool erstellte Tabelle weist das folgende Schema auf:
Hinweis
Eine App sollte Cachewerte mithilfe einer Instanz von IDistributedCache, nicht von SqlServerCache, bearbeiten.
Die Beispiel-App implementiert SqlServerCache in einer Nicht-Entwicklungsumgebung in Program.cs
:
builder.Services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString(
"DistCache_ConnectionString");
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Hinweis
ConnectionString sowie optional SchemaName und TableName werden in der Regel außerhalb der Quellcodeverwaltung gespeichert (z. B. vom Secret Manager oder in appsettings.json
/appsettings.{Environment}.json
-Dateien gespeichert). Die Verbindungszeichenfolge kann Anmeldeinformationen enthalten, die außerhalb der Quellcodeverwaltungssysteme aufbewahrt werden sollten.
Verteilter NCache-Cache
NCache ist ein verteilter Open Source In-Memory-Cache, der nativ in .NET und .NET Core entwickelt wurde. NCache funktioniert sowohl lokal als auch als verteilter Cachecluster für eine ASP.NET Core-App, die in Azure oder auf anderen Hostingplattformen ausgeführt wird.
Informationen zum Installieren und Konfigurieren von NCache auf Ihrem lokalen Computer finden Sie unter Leitfaden mit ersten Schritten für Windows (.NET und .NET Core).
So konfigurieren Sie NCache:
- Installieren Sie NCache Open Source NuGet.
- Konfigurieren Sie den Cachecluster in client.ncconf.
- Fügen Sie den folgenden Code zu
Program.cs
hinzu:
builder.Services.AddNCacheDistributedCache(configuration =>
{
configuration.CacheName = "democache";
configuration.EnableLogs = true;
configuration.ExceptionsEnabled = true;
});
Verwenden des verteilten Cache
Um die IDistributedCache-Schnittstelle zu verwenden, fordern Sie eine Instanz von IDistributedCache in der App an. Die Instanz wird durch Abhängigkeitsinjektion (Dependency Injection, DI) bereitgestellt.
Wenn die Beispiel-App gestartet wird, wird IDistributedCache in Program.cs
eingebracht. Die aktuelle Zeit wird mit IHostApplicationLifetime zwischengespeichert (weitere Informationen finden Sie unter Generischer 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);
});
Die Beispiel-App bringt IDistributedCache zwecks Verwendung durch die Indexseite in IndexModel
ein.
Jedes Mal, wenn die Indexseite geladen wird, wird der Cache auf die zwischengespeicherte Zeit in OnGetAsync
überprüft. Wenn die zwischengespeicherte Zeit nicht abgelaufen ist, wird die Uhrzeit angezeigt. Wenn seit dem letzten Zugriff auf die zwischengespeicherte Zeit (das letzte Laden dieser Seite) 20 Sekunden verstrichen sind, wird auf der Seite Zwischengespeicherte Zeit abgelaufen angezeigt.
Aktualisieren Sie sofort die zwischengespeicherte Zeit auf die aktuelle Zeit, indem Sie die Schaltfläche Zwischengespeicherte Zeit zurücksetzen auswählen. Die Schaltfläche löst die Handlermethode OnPostResetCachedTime
aus.
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();
}
}
Es ist nicht erforderlich, eine Singleton- oder bereichsbezogene Lebensdauer für IDistributedCache-Instanzen mit den integrierten Implementierungen zu verwenden.
Sie können zudem eine IDistributedCache-Instanz überall dort erstellen, wo Sie anstelle von DI eine Instanz benötigen, aber das Erstellen einer Instanz im Code kann das Testen Ihres Codes erschweren und gegen das Prinzip der expliziten Abhängigkeiten verstoßen.
Empfehlungen
Bei der Entscheidung, welche Implementierung von IDistributedCache für Ihre App am besten geeignet ist, sollten Sie Folgendes berücksichtigen:
- Vorhandene Infrastruktur
- Leistungsanforderungen
- Kosten
- Teamerfahrung
Zwischenspeicherlösungen basieren in der Regel auf In-Memory-Speicher, um einen schnellen Abruf von zwischengespeicherten Daten zu ermöglichen. Der Arbeitsspeicher ist jedoch nur eine begrenzte Ressource und seine Erweiterung kostspielig. Speichern Sie nur häufig verwendete Daten in einem Cache.
Für die meisten Apps bietet ein Redis-Cache einen höheren Durchsatz und eine geringere Latenz als ein SQL Server-Cache. Es wird jedoch ein Benchmarking empfohlen, um die Leistungsmerkmale von Zwischenspeicherungsstrategien zu bestimmen.
Wenn SQL Server als verteilter Cachesicherungsspeicher verwendet wird, kann sich die Verwendung derselben Datenbank für den Cache und die normale Datenspeicherung der App und das Abrufen negativ auf die Leistung beider auswirken. Es wird empfohlen, eine dedizierte SQL Server-Instanz für den verteilten Cachesicherungsspeicher zu verwenden.
Zusätzliche Ressourcen
- Redis Cache in Azure
- SQL-Datenbank in Azure
- ASP.NET Core IDistributedCache-Anbieter für NCache in Webfarmen (NCache in GitHub)
- Zwischenspeichern im Arbeitsspeicher in ASP.NET Core
- Erkennen von Änderungen mit Änderungstoken in ASP.NET Core
- Zwischenspeichern von Antworten in ASP.NET Core
- Middleware für das Zwischenspeichern von Antworten in ASP.NET Core
- Cache-Taghilfsprogramm im ASP.NET Core MVC
- Taghilfsprogramm für verteilten Cache in ASP.NET Core
- Hosten von ASP.NET Core in einer Webfarm
Ein verteilter Cache ist ein Cache, der von mehreren App-Servern gemeinsam genutzt wird und in der Regel als externer Dienst für die App-Server verwaltet wird, die darauf zugreifen. Ein verteilter Cache kann die Leistung und Skalierbarkeit einer ASP.NET Core-App verbessern, insbesondere wenn die App von einem Clouddienst oder einer Serverfarm gehostet wird.
Ein verteilter Cache hat mehrere Vorteile gegenüber anderen Zwischenspeicherungsszenarien, in denen zwischengespeicherte Daten auf einzelnen App-Servern gespeichert werden.
Wenn zwischengespeicherte Daten verteilt werden, gilt für sie Folgendes:
- Sie sind kohärent (konsistent) für Anforderungen an mehrere Server.
- Sie überleben Serverneustarts und App-Bereitstellungen.
- Sie verwenden keinen lokalen Arbeitsspeicher.
Die Konfiguration des verteilten Cache ist implementierungsspezifisch. In diesem Artikel wird beschrieben, wie Sie verteilte Caches von SQL Server und Redis konfigurieren. Drittanbieterimplementierungen sind ebenfalls verfügbar, z. B. NCache (NCache auf GitHub). Unabhängig davon, welche Implementierung ausgewählt ist, interagiert die App über die Schnittstelle IDistributedCache mit dem Cache.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Voraussetzungen
Um einen verteilten SQL Server-Cache zu verwenden, fügen Sie dem Paket Microsoft.Extensions.Caching.SqlServer einen Paketverweis hinzu.
Um einen verteilten Redis-Cache zu verwenden, fügen Sie dem Paket Microsoft.Extensions.Caching.StackExchangeRedis einen Paketverweis hinzu.
Um den verteilten NCache-Cache zu verwenden, fügen Sie dem Paket NCache.Microsoft.Extensions.Caching.OpenSource einen Paketverweis hinzu.
IDistributedCache-Schnittstelle
Die IDistributedCache-Schnittstelle bietet die folgenden Methoden zum Bearbeiten von Elementen bei der Implementierung des verteilten Cache:
- Get, GetAsync: Akzeptiert einen Zeichenfolgenschlüssel und ruft ein zwischengespeichertes Element als
byte[]
-Array ab, wenn es im Cache gefunden wird. - Set, SetAsync: Fügt dem Cache mithilfe eines Zeichenfolgenschlüssels ein Element (als
byte[]
-Array) hinzu. - Refresh, RefreshAsync: Aktualisiert ein Element im Cache auf Grundlage seines Schlüssels und setzt das gleitende Ablauftimeout (sofern vorhanden) zurück.
- Remove, RemoveAsync: Entfernt ein Cacheelement anhand seines Zeichenfolgenschlüssels.
Einrichten verteilter Zwischenspeicherdienste
Registrieren Sie eine Implementierung von IDistributedCache in Startup.ConfigureServices
. Im Framework bereitgestellte Implementierungen, die in diesem Thema beschrieben werden, umfassen:
Verteilter Speichercache
Der verteilte Speichercache (AddDistributedMemoryCache) ist eine vom Framework bereitgestellte Implementierung von IDistributedCache, die Elemente im Arbeitsspeicher speichert. Der verteilte Speichercache ist kein tatsächlich verteilter Cache. Zwischengespeicherte Elemente werden von der App-Instanz auf dem Server gespeichert, auf dem die App ausgeführt wird.
Der verteilte Speichercache ist eine nützliche Implementierung:
- In Entwicklungs- und Testszenarien.
- Wenn ein einzelner Server in der Produktion verwendet wird und die Arbeitsspeichernutzung kein Problem ist. Durch die Implementierung des verteilten Speichercache wird die Speicherung von Cachedaten abstrahiert. Dies ermöglicht die Implementierung einer echten verteilten Zwischenspeicherungslösung in der Zukunft, wenn mehrere Knoten oder Fehlertoleranz erforderlich werden.
Die Beispiel-App verwendet den verteilten Speichercache, wenn die App in der Entwicklungsumgebung in Startup.ConfigureServices
ausgeführt wird:
services.AddDistributedMemoryCache();
Verteilter SQL Server-Cache
Die Implementierung des verteilten SQL Server-Cache (AddDistributedSqlServerCache) ermöglicht es dem verteilten Cache, eine SQL Server-Datenbank als Sicherungsspeicher zu verwenden. Um eine zwischengespeicherte SQL Server.Elementtabelle in einer SQL Server-Instanz zu erstellen, können Sie das Tool sql-cache
verwenden. Das Tool erstellt eine Tabelle mit dem von Ihnen angegebenen Namen und Schema.
Erstellen Sie eine Tabelle in SQL Server, indem Sie den Befehl sql-cache create
ausführen. Geben Sie die SQL Server-Instanz (Data Source
), die Datenbank (Initial Catalog
), das Schema (z. B. dbo
) und den Tabellennamen (z. B. TestCache
) an:
dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
Eine Meldung wird protokolliert, um anzugeben, dass das Tool erfolgreich war:
Table and index were created successfully.
Die vom sql-cache
-Tool erstellte Tabelle weist das folgende Schema auf:
Hinweis
Eine App sollte Cachewerte mithilfe einer Instanz von IDistributedCache, nicht von SqlServerCache, bearbeiten.
Die Beispiel-App implementiert SqlServerCache in einer Nicht-Entwicklungsumgebung in Startup.ConfigureServices
:
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString =
_config["DistCache_ConnectionString"];
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Hinweis
ConnectionString sowie optional SchemaName und TableName werden in der Regel außerhalb der Quellcodeverwaltung gespeichert (z. B. vom Secret Manager oder in appsettings.json
/appsettings.{Environment}.json
-Dateien gespeichert). Die Verbindungszeichenfolge kann Anmeldeinformationen enthalten, die außerhalb der Quellcodeverwaltungssysteme aufbewahrt werden sollten.
Verteilter Redis-Cache
Redis ist ein Open Source In-Memory-Datenspeicher, der häufig als verteilter Cache verwendet wird. Sie können einen Azure Redis Cache für eine von Azure gehostete ASP.NET Core-App konfigurieren und einen Azure Redis Cache für die lokale Entwicklung verwenden.
Eine App konfiguriert die Cacheimplementierung mithilfe einer RedisCache-Instanz (AddStackExchangeRedisCache).
- Erstellen Sie einen Azure Cache for Redis.
- Kopieren Sie die primäre Verbindungszeichenfolge (StackExchange.Redis) in Configuration.
- Lokale Entwicklung: Speichern Sie die Verbindungszeichenfolge mit Secret Manager.
- Azure: Speichern der Verbindungszeichenfolge in einem sicheren Speicher wie Azure Key Vault
Der folgende Code aktiviert 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();
}
Im vorherigen Code wird davon ausgegangen, dass die primäre Verbindungszeichenfolge (StackExchange.Redis) in Configuration mit dem Schlüsselnamen MyRedisConStr
gespeichert wurde.
Weitere Informationen finden Sie unter Azure Cache for Redis.
In diesem GitHub-Problem finden Sie eine Diskussion zu alternativen Ansätzen für einen lokalen Redis-Cache.
Verteilter NCache-Cache
NCache ist ein verteilter Open Source In-Memory-Cache, der nativ in .NET und .NET Core entwickelt wurde. NCache funktioniert sowohl lokal als auch als verteilter Cachecluster für eine ASP.NET Core-App, die in Azure oder auf anderen Hostingplattformen ausgeführt wird.
Informationen zum Installieren und Konfigurieren von NCache auf Ihrem lokalen Computer finden Sie unter Leitfaden mit ersten Schritten für Windows (.NET und .NET Core).
So konfigurieren Sie NCache:
Installieren Sie NCache Open Source NuGet.
Konfigurieren Sie den Cachecluster in client.ncconf.
Fügen Sie den folgenden Code zu
Startup.ConfigureServices
hinzu:services.AddNCacheDistributedCache(configuration => { configuration.CacheName = "demoClusteredCache"; configuration.EnableLogs = true; configuration.ExceptionsEnabled = true; });
Verwenden des verteilten Cache
Um die IDistributedCache-Schnittstelle zu verwenden, fordern Sie eine Instanz von IDistributedCache von einem beliebigen Konstruktor in der App an. Die Instanz wird durch Abhängigkeitsinjektion (Dependency Injection, DI) bereitgestellt.
Wenn die Beispiel-App gestartet wird, wird IDistributedCache in Startup.Configure
eingebracht. Die aktuelle Zeit wird mit IHostApplicationLifetime zwischengespeichert (weitere Informationen finden Sie unter Generischer 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);
});
Die Beispiel-App bringt IDistributedCache zwecks Verwendung durch die Indexseite in IndexModel
ein.
Jedes Mal, wenn die Indexseite geladen wird, wird der Cache auf die zwischengespeicherte Zeit in OnGetAsync
überprüft. Wenn die zwischengespeicherte Zeit nicht abgelaufen ist, wird die Uhrzeit angezeigt. Wenn seit dem letzten Zugriff auf die zwischengespeicherte Zeit (das letzte Laden dieser Seite) 20 Sekunden verstrichen sind, wird auf der Seite Zwischengespeicherte Zeit abgelaufen angezeigt.
Aktualisieren Sie sofort die zwischengespeicherte Zeit auf die aktuelle Zeit, indem Sie die Schaltfläche Zwischengespeicherte Zeit zurücksetzen auswählen. Die Schaltfläche löst die Handlermethode OnPostResetCachedTime
aus.
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();
}
}
Hinweis
Es ist nicht erforderlich, eine Singleton- oder bereichsbezogene Lebensdauer für IDistributedCache-Instanzen (zumindest für die integrierten Implementierungen) zu verwenden.
Sie können zudem eine IDistributedCache-Instanz überall dort erstellen, wo Sie anstelle von DI eine Instanz benötigen, aber das Erstellen einer Instanz im Code kann das Testen Ihres Codes erschweren und gegen das Prinzip der expliziten Abhängigkeiten verstoßen.
Empfehlungen
Bei der Entscheidung, welche Implementierung von IDistributedCache für Ihre App am besten geeignet ist, sollten Sie Folgendes berücksichtigen:
- Vorhandene Infrastruktur
- Leistungsanforderungen
- Kosten
- Teamerfahrung
Zwischenspeicherlösungen basieren in der Regel auf In-Memory-Speicher, um einen schnellen Abruf von zwischengespeicherten Daten zu ermöglichen. Der Arbeitsspeicher ist jedoch nur eine begrenzte Ressource und seine Erweiterung kostspielig. Speichern Sie nur häufig verwendete Daten in einem Cache.
Im Allgemeinen bietet ein Redis-Cache einen höheren Durchsatz und eine geringere Latenzzeit als ein SQL Server-Cache. Es ist jedoch in der Regel ein Benchmarking erforderlich, um die Leistungsmerkmale von Zwischenspeicherungsstrategien zu bestimmen.
Wenn SQL Server als verteilter Cachesicherungsspeicher verwendet wird, kann sich die Verwendung derselben Datenbank für den Cache und die normale Datenspeicherung der App und das Abrufen negativ auf die Leistung beider auswirken. Es wird empfohlen, eine dedizierte SQL Server-Instanz für den verteilten Cachesicherungsspeicher zu verwenden.
Zusätzliche Ressourcen
- Redis Cache in Azure
- SQL-Datenbank in Azure
- ASP.NET Core IDistributedCache-Anbieter für NCache in Webfarmen (NCache in GitHub)
- Zwischenspeichern im Arbeitsspeicher in ASP.NET Core
- Erkennen von Änderungen mit Änderungstoken in ASP.NET Core
- Zwischenspeichern von Antworten in ASP.NET Core
- Middleware für das Zwischenspeichern von Antworten in ASP.NET Core
- Cache-Taghilfsprogramm im ASP.NET Core MVC
- Taghilfsprogramm für verteilten Cache in ASP.NET Core
- Hosten von ASP.NET Core in einer Webfarm