Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Por Mohsin Nasir e smandia
Note
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.
Warning
Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Um cache distribuído é um cache compartilhado por vários servidores de aplicativos, normalmente mantido como um serviço externo aos servidores de aplicativos que o acessam. Um cache distribuído pode melhorar o desempenho e a escalabilidade de um aplicativo ASP.NET Core, especialmente quando o aplicativo é hospedado por um serviço de nuvem ou um farm de servidores.
Um cache distribuído tem várias vantagens em relação a outros cenários de cache em que os dados armazenados em cache são armazenados em servidores de aplicativos individuais.
Quando os dados armazenados em cache são distribuídos, os dados:
- É coerente (consistente) entre solicitações para vários servidores.
- Sobrevive a reinicializações de servidores e implantações de aplicativos.
- Não usa memória local.
A configuração do cache distribuído é específica da implementação. Este artigo descreve como configurar caches distribuídos do SQL Server, Redis ou Postgres. Implementações de terceiros também estão disponíveis, como NCache (NCache no GitHub), Cosmos DB e Postgres. Independentemente da implementação selecionada, o aplicativo interage com o cache usando a IDistributedCache interface.
Visualizar ou descarregar amostra de código (como descarregar)
Warning
Este artigo usa um banco de dados local que não exige que o usuário seja autenticado. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos de teste e produção implantados, consulte Fluxos de autenticação seguros.
Prerequisites
Adicione uma referência de pacote para o provedor de cache distribuído usado:
- Para um cache distribuído Redis, Microsoft.Extensions.Caching.StackExchangeRedis.
- Para SQL Server, Microsoft.Extensions.Caching.SqlServer.
- Para Postgres, Microsoft.Extensions.Caching.Postgres.
- Para o Cosmos DB, Microsoft.Extensions.Caching.Cosmos.
- Para o cache distribuído NCache, NCache.Microsoft.Extensions.Caching.OpenSource.
Interface IDistributedCache
A IDistributedCache interface fornece os seguintes métodos para manipular itens na implementação de cache distribuído:
-
Get, GetAsync: Aceita uma chave de cadeia de caracteres e recupera um item armazenado em cache como uma
byte[]matriz, se encontrado no cache. -
Set, SetAsync: Adiciona um item (como
byte[]matriz) ao cache usando uma chave de cadeia de caracteres. - Refresh, RefreshAsync: Atualiza um item no cache com base em sua chave, redefinindo seu tempo limite de expiração deslizante (se houver).
- Remove, RemoveAsync: Remove um item de cache com base em sua chave de cadeia de caracteres.
Estabelecer serviços de cache distribuído
Registrar uma implementação de IDistributedCache em Program.cs. As implementações fornecidas pela estrutura descritas neste tópico incluem:
- Cache Redis distribuído
- Cache de memória distribuída
- Cache distribuído do SQL Server
- Cache Postgres distribuído
- Cache NCache distribuído
- Cache distribuído do Azure Cosmos DB
Cache Redis Distribuído
Recomendamos que os aplicativos de produção usem o Cache Redis Distribuído porque ele é o mais eficiente. Para obter mais informações, consulte Recomendações.
O Redis é um armazenamento de dados na memória de código aberto, que é frequentemente usado como um cache distribuído. Você pode configurar um Cache do Azure para Redis para um aplicativo ASP.NET Core hospedado no Azure e usar um Cache do Azure para Redis para desenvolvimento local.
Um aplicativo configura a implementação do cache usando uma RedisCache instância, chamando AddStackExchangeRedisCache. Para cache de saída, use AddStackExchangeRedisOutputCache.
- Crie um cache do Azure para Redis.
- Copie a cadeia de conexão primária (StackExchange.Redis) para Configuration.
- Desenvolvimento local: Salve a cadeia de conexão com o Secret Manager.
- Azure: Salve a cadeia de conexão em um repositório seguro, como o Azure Key Vault
O código a seguir habilita o Cache do Azure para Redis:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
options.InstanceName = "SampleInstance";
});
O código anterior pressupõe que a cadeia de conexão primária (StackExchange.Redis) foi guardada na configuração com o nome da chave MyRedisConStr.
Para obter mais informações, veja Azure Cache for Redis (Cache do Azure para Redis).
Consulte esta questão do GitHub para uma discussão sobre abordagens alternativas a um cache Redis local.
Cache de memória distribuída
O Cache de Memória Distribuída (AddDistributedMemoryCache) é uma implementação fornecida pela estrutura IDistributedCache que armazena itens na memória. O Cache de Memória Distribuída não é um cache distribuído real. Os itens armazenados em cache são armazenados pela instância do aplicativo no servidor em que o aplicativo está sendo executado.
O cache de memória distribuída é uma implementação útil:
- Em cenários de desenvolvimento e teste.
- Quando um único servidor é usado na produção e o consumo de memória não é um problema. A implementação do Cache de Memória Distribuída abstrai o armazenamento de dados em cache. Ele permite a implementação de uma verdadeira solução de cache distribuído no futuro, caso vários nós ou a necessidade de tolerância a falhas se tornem necessários.
O aplicativo de exemplo usa o Cache de Memória Distribuída quando o aplicativo é executado no ambiente de desenvolvimento em Program.cs:
builder.Services.AddDistributedMemoryCache();
Cache distribuído do SQL Server
A implementação do Cache Distribuído do SQL Server (AddDistributedSqlServerCache) permite que o cache distribuído use um banco de dados do SQL Server como seu armazenamento de backup. Para criar uma tabela de itens em cache do SQL Server em uma instância do SQL Server, você pode usar a sql-cache ferramenta. A ferramenta cria uma tabela com o nome e o esquema especificados.
Crie uma tabela no SQL Server executando o sql-cache create comando. Forneça a instância do SQL Server (Data Source), o banco de dados (Initial Catalog), o esquema (por exemplo, dbo) e o nome da tabela (por exemplo, TestCache):
dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
Uma mensagem é registrada para indicar que a ferramenta foi bem-sucedida:
Table and index were created successfully.
A tabela criada pela sql-cache ferramenta tem o seguinte esquema:
Note
Uma aplicação deve manipular valores de cache usando uma instância de IDistributedCache, não um SqlServerCache.
O aplicativo de SqlServerCache exemplo é implementado em um ambiente que não é de desenvolvimento em Program.cs:
builder.Services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString(
"DistCache_ConnectionString");
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Note
A ConnectionString (e, opcionalmente, SchemaName e TableName) são normalmente armazenados fora do controle do código-fonte (por exemplo, armazenados pelo Gerenciador Secreto ou em appsettings.json/appsettings.{Environment}.json arquivos). A cadeia de conexão pode conter credenciais que devem ser mantidas fora dos sistemas de controle do código-fonte.
Cache Postgres distribuído
O Banco de Dados do Azure para PostgreSQL pode ser usado como um armazenamento de backup de cache distribuído por meio da IDistributedCache interface. O Banco de Dados do Azure para PostgreSQL é uma oferta de Banco de Dados como Serviço (DBaaS) totalmente gerenciada e pronta para IA criada no mecanismo PostgreSQL de código aberto, projetada para dar suporte a cargas de trabalho de missão crítica com desempenho previsível, segurança robusta, alta disponibilidade e escalabilidade perfeita.
Depois de instalar o pacote NuGet Microsoft.Extensions.Caching.Postgres , configure o cache distribuído da seguinte maneira:
- Registar o Serviço
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Register Postgres distributed cache
builder.Services.AddDistributedPostgresCache(options => {
options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache");
options.SchemaName = builder.Configuration.GetValue<string>("PostgresCache:SchemaName", "public");
options.TableName = builder.Configuration.GetValue<string>("PostgresCache:TableName", "cache");
options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists", true);
options.UseWAL = builder.Configuration.GetValue<bool>("PostgresCache:UseWAL", false);
// Optional: Configure expiration settings
var expirationInterval = builder.Configuration.GetValue<string>("PostgresCache:ExpiredItemsDeletionInterval");
if (!string.IsNullOrEmpty(expirationInterval) && TimeSpan.TryParse(expirationInterval, out var interval)) {
options.ExpiredItemsDeletionInterval = interval;
}
var slidingExpiration = builder.Configuration.GetValue<string>("PostgresCache:DefaultSlidingExpiration");
if (!string.IsNullOrEmpty(slidingExpiration) && TimeSpan.TryParse(slidingExpiration, out var sliding)) {
options.DefaultSlidingExpiration = sliding;
}
});
var app = builder.Build();
- Usar o cache
public class MyService {
private readonly IDistributedCache _cache;
public MyService(IDistributedCache cache) {
_cache = cache;
}
public async Task<string> GetDataAsync(string key) {
var cachedData = await _cache.GetStringAsync(key);
if (cachedData == null) {
// Fetch data from source
var data = await FetchDataFromSource();
// Cache the data with options
var options = new DistributedCacheEntryOptions {
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30),
SlidingExpiration = TimeSpan.FromMinutes(5)
};
await _cache.SetStringAsync(key, data, options);
return data;
}
return cachedData;
}
}
Cache distribuído NCache
NCache é um cache distribuído em memória de código aberto desenvolvido nativamente em .NET. O NCache funciona localmente e configurado como um cluster de cache distribuído para um aplicativo ASP.NET Core em execução no Azure ou em outras plataformas de hospedagem.
Para instalar e configurar o NCache em sua máquina local, consulte Guia de Introdução para Windows & Linux.
Para configurar o NCache:
- Instale NuGet de código aberto NCache.
- Configure o cluster de cache em client.ncconf.
- Adicione o seguinte código ao
Program.cs:
builder.Services.AddNCacheDistributedCache(configuration =>
{
configuration.CacheName = "democache";
configuration.EnableLogs = true;
configuration.ExceptionsEnabled = true;
});
Cache distribuído do Azure Cosmos DB
O Azure Cosmos DB pode ser usado no ASP.NET Core como um provedor de estado de sessão usando a IDistributedCache interface. O Azure Cosmos DB é um banco de dados relacional e NoSQL totalmente gerenciado para desenvolvimento de aplicativos modernos que oferece alta disponibilidade, escalabilidade e acesso de baixa latência a dados para aplicativos de missão crítica.
Depois de instalar o pacote NuGet Microsoft.Extensions.Caching.Cosmos , configure um cache distribuído do Azure Cosmos DB da seguinte maneira:
Reutilizar um cliente existente
A maneira mais fácil de configurar o cache distribuído é reutilizando um cliente existente do Azure Cosmos DB. Nesse caso, a instância CosmosClient não será descartada quando o provedor for descartado.
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
cacheOptions.CosmosClient = existingCosmosClient;
cacheOptions.CreateIfNotExists = true;
});
Criar um novo cliente
Como alternativa, instancie um novo cliente. Nesse caso, a instância CosmosClient será descartada quando o provedor for descartado.
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]);
cacheOptions.CreateIfNotExists = true;
});
Usar o cache distribuído
Para usar a IDistributedCache interface, solicite uma instância de IDistributedCache no aplicativo. A instância é fornecida por injeção de dependência (DI).
Quando o aplicativo de exemplo é iniciado, IDistributedCache é injetado no Program.cs. A hora atual é armazenada em cache usando IHostApplicationLifetime (para obter mais informações, consulte Host genérico: 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);
});
O aplicativo de exemplo injeta IDistributedCache no IndexModel para uso pela página Índice.
Cada vez que a página Índice é carregada, o cache é verificado para o tempo armazenado em cache no OnGetAsync. Se o tempo armazenado em cache não tiver expirado, o tempo será exibido. Se tiverem decorrido 20 segundos desde a última vez que a hora em cache foi acedida (a última vez que esta página foi carregada), a página apresenta Tempo em Cache Expirado.
Atualize imediatamente a hora armazenada em cache para a hora atual selecionando o botão Redefinir hora em cache . O botão aciona o método manipulador OnPostResetCachedTime.
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();
}
}
Não há necessidade de usar um ciclo de vida Singleton ou Scoped para IDistributedCache instâncias com as implementações incorporadas.
Você também pode criar uma IDistributedCache instância sempre que precisar de uma em vez de usar DI, mas criar uma instância no código pode tornar seu código mais difícil de testar e viola o Princípio de Dependências Explícitas.
Recommendations
Ao decidir qual implementação de IDistributedCache é a melhor para o seu aplicativo, considere o seguinte:
- Infraestrutura existente
- Requisitos de desempenho
- Cost
- Experiência de equipa
As soluções de cache geralmente dependem do armazenamento na memória para fornecer recuperação rápida de dados armazenados em cache, mas a memória é um recurso limitado e caro para expandir. Armazene apenas os dados mais usados em um cache.
Para a maioria dos aplicativos, um cache Redis fornece maior taxa de transferência e menor latência do que um cache do SQL Server. No entanto, recomenda-se o benchmarking para determinar as características de desempenho das estratégias de cache.
Quando o SQL Server é usado como um armazenamento de backup de cache distribuído, o uso do mesmo banco de dados para o cache e o armazenamento e recuperação de dados comuns do aplicativo podem afetar negativamente o desempenho de ambos. Recomendamos o uso de uma instância dedicada do SQL Server para o armazenamento de backup de cache distribuído.
Recursos adicionais
- Redis Cache no Azure
- Banco de Dados SQL no Azure
- Base de Dados do Azure para PostgreSQL
- ASP.NET Core IDistributedCache Provider para NCache em Web Farms (NCache no GitHub)
- Ficheiro README do repositório para Microsoft.Extensions.Caching.Cosmos
- Cache na memória no ASP.NET Core
- Detectar alterações com tokens de alteração no ASP.NET Core
- Cache de Resposta no ASP.NET Core
- Middleware de Cache de Resposta no ASP.NET Core
- Tag Helper de Cache em ASP.NET Core MVC
- auxiliar de tag de cache distribuído no ASP.NET Core
- Hospedar ASP.NET Core em uma web farm
Um cache distribuído é um cache compartilhado por vários servidores de aplicativos, normalmente mantido como um serviço externo aos servidores de aplicativos que o acessam. Um cache distribuído pode melhorar o desempenho e a escalabilidade de um aplicativo ASP.NET Core, especialmente quando o aplicativo é hospedado por um serviço de nuvem ou um farm de servidores.
Um cache distribuído tem várias vantagens em relação a outros cenários de cache em que os dados armazenados em cache são armazenados em servidores de aplicativos individuais.
Quando os dados armazenados em cache são distribuídos, os dados:
- É coerente (consistente) entre solicitações para vários servidores.
- Sobrevive a reinicializações de servidores e implantações de aplicativos.
- Não usa memória local.
A configuração do cache distribuído é específica da implementação. Este artigo descreve como configurar caches distribuídos do SQL Server, Redis e Postgres. Implementações de terceiros também estão disponíveis, como NCache (NCache no GitHub). Independentemente da implementação selecionada, o aplicativo interage com o cache usando a IDistributedCache interface.
Visualizar ou descarregar amostra de código (como descarregar)
Prerequisites
Adicione uma referência de pacote para o provedor de cache distribuído usado:
Para um cache distribuído Redis, Microsoft.Extensions.Caching.StackExchangeRedis.
Para SQL Server, Microsoft.Extensions.Caching.SqlServer.
Para Postgres, Microsoft.Extensions.Caching.Postgres.
Para o cache distribuído NCache, NCache.Microsoft.Extensions.Caching.OpenSource.
-
Warning
Este artigo usa um banco de dados local que não exige que o usuário seja autenticado. Os aplicativos de produção devem usar o fluxo de autenticação mais seguro disponível. Para obter mais informações sobre autenticação para aplicativos de teste e produção implantados, consulte Fluxos de autenticação seguros.
Interface IDistributedCache
A IDistributedCache interface fornece os seguintes métodos para manipular itens na implementação de cache distribuído:
-
Get, GetAsync: Aceita uma chave de cadeia de caracteres e recupera um item armazenado em cache como uma
byte[]matriz, se encontrado no cache. -
Set, SetAsync: Adiciona um item (como
byte[]matriz) ao cache usando uma chave de cadeia de caracteres. - Refresh, RefreshAsync: Atualiza um item no cache com base em sua chave, redefinindo seu tempo limite de expiração deslizante (se houver).
- Remove, RemoveAsync: Remove um item de cache com base em sua chave de cadeia de caracteres.
Estabelecer serviços de cache distribuído
Registrar uma implementação de IDistributedCache em Program.cs. As implementações fornecidas pela estrutura descritas neste tópico incluem:
- Cache Redis distribuído
- Cache de memória distribuída
- Cache distribuído do SQL Server
- Cache Postgres distribuído
- Cache NCache distribuído
Cache Redis Distribuído
Recomendamos que os aplicativos de produção usem o Cache Redis Distribuído porque ele é o mais eficiente. Para obter mais informações, consulte Recomendações.
O Redis é um armazenamento de dados na memória de código aberto, que é frequentemente usado como um cache distribuído. Você pode configurar um Cache Redis do Azure para um aplicativo ASP.NET Core hospedado no Azure e usar um Cache Redis do Azure para desenvolvimento local.
Um aplicativo configura a implementação de cache usando uma RedisCache instância (AddStackExchangeRedisCache).
- Crie um cache do Azure para Redis.
- Copie a cadeia de conexão primária (StackExchange.Redis) para Configuration.
- Desenvolvimento local: Salve a cadeia de conexão com o Secret Manager.
- Azure: Salve a cadeia de conexão em um repositório seguro, como o Azure Key Vault
O código a seguir habilita o Cache do Azure para Redis:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
options.InstanceName = "SampleInstance";
});
O código anterior pressupõe que a cadeia de conexão primária (StackExchange.Redis) foi guardada na configuração com o nome da chave MyRedisConStr.
Para obter mais informações, veja Azure Cache for Redis (Cache do Azure para Redis).
Consulte esta questão do GitHub para uma discussão sobre abordagens alternativas a um cache Redis local.
Cache de memória distribuída
O Cache de Memória Distribuída (AddDistributedMemoryCache) é uma implementação fornecida pela estrutura IDistributedCache que armazena itens na memória. O Cache de Memória Distribuída não é um cache distribuído real. Os itens armazenados em cache são armazenados pela instância do aplicativo no servidor em que o aplicativo está sendo executado.
O cache de memória distribuída é uma implementação útil:
- Em cenários de desenvolvimento e teste.
- Quando um único servidor é usado na produção e o consumo de memória não é um problema. A implementação do Cache de Memória Distribuída abstrai o armazenamento de dados em cache. Ele permite a implementação de uma verdadeira solução de cache distribuído no futuro, caso vários nós ou a necessidade de tolerância a falhas se tornem necessários.
O aplicativo de exemplo usa o Cache de Memória Distribuída quando o aplicativo é executado no ambiente de desenvolvimento em Program.cs:
builder.Services.AddDistributedMemoryCache();
Cache distribuído do SQL Server
A implementação do Cache Distribuído do SQL Server (AddDistributedSqlServerCache) permite que o cache distribuído use um banco de dados do SQL Server como seu armazenamento de backup. Para criar uma tabela de itens em cache do SQL Server em uma instância do SQL Server, você pode usar a sql-cache ferramenta. A ferramenta cria uma tabela com o nome e o esquema especificados.
Crie uma tabela no SQL Server executando o sql-cache create comando. Forneça a instância do SQL Server (Data Source), o banco de dados (Initial Catalog), o esquema (por exemplo, dbo) e o nome da tabela (por exemplo, TestCache):
dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
Uma mensagem é registrada para indicar que a ferramenta foi bem-sucedida:
Table and index were created successfully.
A tabela criada pela sql-cache ferramenta tem o seguinte esquema:
Note
Uma aplicação deve manipular valores de cache usando uma instância de IDistributedCache, não um SqlServerCache.
O aplicativo de SqlServerCache exemplo é implementado em um ambiente que não é de desenvolvimento em Program.cs:
builder.Services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString(
"DistCache_ConnectionString");
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Note
A ConnectionString (e, opcionalmente, SchemaName e TableName) são normalmente armazenados fora do controle do código-fonte (por exemplo, armazenados pelo Gerenciador Secreto ou em appsettings.json/appsettings.{Environment}.json arquivos). A cadeia de conexão pode conter credenciais que devem ser mantidas fora dos sistemas de controle do código-fonte.
Cache Postgres distribuído
O Banco de Dados do Azure para PostgreSQL pode ser usado como um armazenamento de backup de cache distribuído por meio da IDistributedCache interface. O Banco de Dados do Azure para PostgreSQL é uma oferta de Banco de Dados como Serviço (DBaaS) totalmente gerenciada e pronta para IA criada no mecanismo PostgreSQL de código aberto, projetada para dar suporte a cargas de trabalho de missão crítica com desempenho previsível, segurança robusta, alta disponibilidade e escalabilidade perfeita.
Depois de instalar o pacote NuGet Microsoft.Extensions.Caching.Postgres , configure o cache distribuído da seguinte maneira:
- Registar o Serviço
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Register Postgres distributed cache
builder.Services.AddDistributedPostgresCache(options => {
options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache");
options.SchemaName = builder.Configuration.GetValue<string>("PostgresCache:SchemaName", "public");
options.TableName = builder.Configuration.GetValue<string>("PostgresCache:TableName", "cache");
options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists", true);
options.UseWAL = builder.Configuration.GetValue<bool>("PostgresCache:UseWAL", false);
// Optional: Configure expiration settings
var expirationInterval = builder.Configuration.GetValue<string>("PostgresCache:ExpiredItemsDeletionInterval");
if (!string.IsNullOrEmpty(expirationInterval) && TimeSpan.TryParse(expirationInterval, out var interval)) {
options.ExpiredItemsDeletionInterval = interval;
}
var slidingExpiration = builder.Configuration.GetValue<string>("PostgresCache:DefaultSlidingExpiration");
if (!string.IsNullOrEmpty(slidingExpiration) && TimeSpan.TryParse(slidingExpiration, out var sliding)) {
options.DefaultSlidingExpiration = sliding;
}
});
var app = builder.Build();
- Usar o cache
public class MyService {
private readonly IDistributedCache _cache;
public MyService(IDistributedCache cache) {
_cache = cache;
}
public async Task<string> GetDataAsync(string key) {
var cachedData = await _cache.GetStringAsync(key);
if (cachedData == null) {
// Fetch data from source
var data = await FetchDataFromSource();
// Cache the data with options
var options = new DistributedCacheEntryOptions {
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30),
SlidingExpiration = TimeSpan.FromMinutes(5)
};
await _cache.SetStringAsync(key, data, options);
return data;
}
return cachedData;
}
}
Cache distribuído NCache
NCache é um cache distribuído em memória de código aberto desenvolvido nativamente em .NET e .NET Core. O NCache funciona localmente e configurado como um cluster de cache distribuído para um aplicativo ASP.NET Core em execução no Azure ou em outras plataformas de hospedagem.
Para instalar e configurar o NCache em sua máquina local, consulte Guia de Introdução para Windows (.NET e .NET Core).
Para configurar o NCache:
- Instale NuGet de código aberto NCache.
- Configure o cluster de cache em client.ncconf.
- Adicione o seguinte código ao
Program.cs:
builder.Services.AddNCacheDistributedCache(configuration =>
{
configuration.CacheName = "democache";
configuration.EnableLogs = true;
configuration.ExceptionsEnabled = true;
});
Usar o cache distribuído
Para usar a IDistributedCache interface, solicite uma instância de IDistributedCache no aplicativo. A instância é fornecida por injeção de dependência (DI).
Quando o aplicativo de exemplo é iniciado, IDistributedCache é injetado no Program.cs. A hora atual é armazenada em cache usando IHostApplicationLifetime (para obter mais informações, consulte Host genérico: 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);
});
O aplicativo de exemplo injeta IDistributedCache no IndexModel para uso pela página Índice.
Cada vez que a página Índice é carregada, o cache é verificado para o tempo armazenado em cache no OnGetAsync. Se o tempo armazenado em cache não tiver expirado, o tempo será exibido. Se tiverem decorrido 20 segundos desde a última vez que a hora em cache foi acedida (a última vez que esta página foi carregada), a página apresenta Tempo em Cache Expirado.
Atualize imediatamente a hora armazenada em cache para a hora atual selecionando o botão Redefinir hora em cache . O botão aciona o método manipulador OnPostResetCachedTime.
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();
}
}
Não há necessidade de usar um ciclo de vida Singleton ou Scoped para IDistributedCache instâncias com as implementações incorporadas.
Você também pode criar uma IDistributedCache instância sempre que precisar de uma em vez de usar DI, mas criar uma instância no código pode tornar seu código mais difícil de testar e viola o Princípio de Dependências Explícitas.
Recommendations
Ao decidir qual implementação de IDistributedCache é a melhor para o seu aplicativo, considere o seguinte:
- Infraestrutura existente
- Requisitos de desempenho
- Cost
- Experiência de equipa
As soluções de cache geralmente dependem do armazenamento na memória para fornecer recuperação rápida de dados armazenados em cache, mas a memória é um recurso limitado e caro para expandir. Armazene apenas os dados mais usados em um cache.
Para a maioria dos aplicativos, um cache Redis fornece maior taxa de transferência e menor latência do que um cache do SQL Server. No entanto, recomenda-se o benchmarking para determinar as características de desempenho das estratégias de cache.
Quando o SQL Server é usado como um armazenamento de backup de cache distribuído, o uso do mesmo banco de dados para o cache e o armazenamento e recuperação de dados comuns do aplicativo podem afetar negativamente o desempenho de ambos. Recomendamos o uso de uma instância dedicada do SQL Server para o armazenamento de backup de cache distribuído.
Recursos adicionais
- Redis Cache no Azure
- Banco de Dados SQL no Azure
- Base de Dados do Azure para PostgreSQL
- ASP.NET Core IDistributedCache Provider para NCache em Web Farms (NCache no GitHub)
- Cache na memória no ASP.NET Core
- Detectar alterações com tokens de alteração no ASP.NET Core
- Cache de Resposta no ASP.NET Core
- Middleware de Cache de Resposta no ASP.NET Core
- Tag Helper de Cache em ASP.NET Core MVC
- auxiliar de tag de cache distribuído no ASP.NET Core
- Hospedar ASP.NET Core em uma web farm
Um cache distribuído é um cache compartilhado por vários servidores de aplicativos, normalmente mantido como um serviço externo aos servidores de aplicativos que o acessam. Um cache distribuído pode melhorar o desempenho e a escalabilidade de um aplicativo ASP.NET Core, especialmente quando o aplicativo é hospedado por um serviço de nuvem ou um farm de servidores.
Um cache distribuído tem várias vantagens em relação a outros cenários de cache em que os dados armazenados em cache são armazenados em servidores de aplicativos individuais.
Quando os dados armazenados em cache são distribuídos, os dados:
- É coerente (consistente) entre solicitações para vários servidores.
- Sobrevive a reinicializações de servidores e implantações de aplicativos.
- Não usa memória local.
A configuração do cache distribuído é específica da implementação. Este artigo descreve como configurar caches distribuídos do SQL Server, Redis e Postgres. Implementações de terceiros também estão disponíveis, como NCache (NCache no GitHub). Independentemente da implementação selecionada, o aplicativo interage com o cache usando a IDistributedCache interface.
Visualizar ou descarregar amostra de código (como descarregar)
Prerequisites
Para usar um cache distribuído do SQL Server, adicione uma referência de pacote ao pacote Microsoft.Extensions.Caching.SqlServer .
Para usar um cache distribuído Redis, adicione uma referência de pacote ao pacote Microsoft.Extensions.Caching.StackExchangeRedis .
Para usar um cache distribuído Postgres, adicione uma referência de pacote ao pacote Microsoft.Extensions.Caching.Postgres .
Para usar o cache distribuído NCache, adicione uma referência de pacote ao pacote NCache.Microsoft.Extensions.Caching.OpenSource .
Interface IDistributedCache
A IDistributedCache interface fornece os seguintes métodos para manipular itens na implementação de cache distribuído:
-
Get, GetAsync: Aceita uma chave de cadeia de caracteres e recupera um item armazenado em cache como uma
byte[]matriz, se encontrado no cache. -
Set, SetAsync: Adiciona um item (como
byte[]matriz) ao cache usando uma chave de cadeia de caracteres. - Refresh, RefreshAsync: Atualiza um item no cache com base em sua chave, redefinindo seu tempo limite de expiração deslizante (se houver).
- Remove, RemoveAsync: Remove um item de cache com base em sua chave de cadeia de caracteres.
Estabelecer serviços de cache distribuído
Registrar uma implementação de IDistributedCache em Startup.ConfigureServices. As implementações fornecidas pela estrutura descritas neste tópico incluem:
- Cache de memória distribuída
- Cache distribuído do SQL Server
- Cache Redis distribuído
- Cache Postgres distribuído
- Cache NCache distribuído
Cache de memória distribuída
O Cache de Memória Distribuída (AddDistributedMemoryCache) é uma implementação fornecida pela estrutura IDistributedCache que armazena itens na memória. O Cache de Memória Distribuída não é um cache distribuído real. Os itens armazenados em cache são armazenados pela instância do aplicativo no servidor em que o aplicativo está sendo executado.
O cache de memória distribuída é uma implementação útil:
- Em cenários de desenvolvimento e teste.
- Quando um único servidor é usado na produção e o consumo de memória não é um problema. A implementação do Cache de Memória Distribuída abstrai o armazenamento de dados em cache. Ele permite a implementação de uma verdadeira solução de cache distribuído no futuro, caso vários nós ou a necessidade de tolerância a falhas se tornem necessários.
O aplicativo de exemplo usa o Cache de Memória Distribuída quando o aplicativo é executado no ambiente de desenvolvimento em Startup.ConfigureServices:
services.AddDistributedMemoryCache();
Cache distribuído do SQL Server
A implementação do Cache Distribuído do SQL Server (AddDistributedSqlServerCache) permite que o cache distribuído use um banco de dados do SQL Server como seu armazenamento de backup. Para criar uma tabela de itens em cache do SQL Server em uma instância do SQL Server, você pode usar a sql-cache ferramenta. A ferramenta cria uma tabela com o nome e o esquema especificados.
Crie uma tabela no SQL Server executando o sql-cache create comando. Forneça a instância do SQL Server (Data Source), o banco de dados (Initial Catalog), o esquema (por exemplo, dbo) e o nome da tabela (por exemplo, TestCache):
dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
Uma mensagem é registrada para indicar que a ferramenta foi bem-sucedida:
Table and index were created successfully.
A tabela criada pela sql-cache ferramenta tem o seguinte esquema:
Note
Uma aplicação deve manipular valores de cache usando uma instância de IDistributedCache, não um SqlServerCache.
O aplicativo de SqlServerCache exemplo é implementado em um ambiente que não é de desenvolvimento em Startup.ConfigureServices:
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString =
_config["DistCache_ConnectionString"];
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Note
A ConnectionString (e, opcionalmente, SchemaName e TableName) são normalmente armazenados fora do controle do código-fonte (por exemplo, armazenados pelo Gerenciador Secreto ou em appsettings.json/appsettings.{Environment}.json arquivos). A cadeia de conexão pode conter credenciais que devem ser mantidas fora dos sistemas de controle do código-fonte.
Cache Redis Distribuído
O Redis é um armazenamento de dados na memória de código aberto, que é frequentemente usado como um cache distribuído. Você pode configurar um Cache Redis do Azure para um aplicativo ASP.NET Core hospedado no Azure e usar um Cache Redis do Azure para desenvolvimento local.
Um aplicativo configura a implementação de cache usando uma RedisCache instância (AddStackExchangeRedisCache).
- Crie um cache do Azure para Redis.
- Copie a cadeia de conexão primária (StackExchange.Redis) para Configuration.
- Desenvolvimento local: Salve a cadeia de conexão com o Secret Manager.
- Azure: Salve a cadeia de conexão em um repositório seguro, como o Azure Key Vault
O código a seguir habilita o Cache do Azure para Redis:
public void ConfigureServices(IServiceCollection services)
{
if (_hostContext.IsDevelopment())
{
services.AddDistributedMemoryCache();
}
else
{
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = _config["MyRedisConStr"];
options.InstanceName = "SampleInstance";
});
}
services.AddRazorPages();
}
O código anterior pressupõe que a cadeia de conexão primária (StackExchange.Redis) foi guardada na configuração com o nome da chave MyRedisConStr.
Para obter mais informações, veja Azure Cache for Redis (Cache do Azure para Redis).
Consulte esta questão do GitHub para uma discussão sobre abordagens alternativas a um cache Redis local.
Cache Postgres distribuído
O Banco de Dados do Azure para PostgreSQL pode ser usado como um armazenamento de backup de cache distribuído por meio da IDistributedCache interface. O Banco de Dados do Azure para PostgreSQL é uma oferta de Banco de Dados como Serviço (DBaaS) totalmente gerenciada e pronta para IA criada no mecanismo PostgreSQL de código aberto, projetada para dar suporte a cargas de trabalho de missão crítica com desempenho previsível, segurança robusta, alta disponibilidade e escalabilidade perfeita.
Depois de instalar o pacote NuGet Microsoft.Extensions.Caching.Postgres , configure o cache distribuído da seguinte maneira:
- Registar o Serviço
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Register Postgres distributed cache
builder.Services.AddDistributedPostgresCache(options => {
options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache");
options.SchemaName = builder.Configuration.GetValue<string>("PostgresCache:SchemaName", "public");
options.TableName = builder.Configuration.GetValue<string>("PostgresCache:TableName", "cache");
options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists", true);
options.UseWAL = builder.Configuration.GetValue<bool>("PostgresCache:UseWAL", false);
// Optional: Configure expiration settings
var expirationInterval = builder.Configuration.GetValue<string>("PostgresCache:ExpiredItemsDeletionInterval");
if (!string.IsNullOrEmpty(expirationInterval) && TimeSpan.TryParse(expirationInterval, out var interval)) {
options.ExpiredItemsDeletionInterval = interval;
}
var slidingExpiration = builder.Configuration.GetValue<string>("PostgresCache:DefaultSlidingExpiration");
if (!string.IsNullOrEmpty(slidingExpiration) && TimeSpan.TryParse(slidingExpiration, out var sliding)) {
options.DefaultSlidingExpiration = sliding;
}
});
var app = builder.Build();
- Usar o cache
public class MyService {
private readonly IDistributedCache _cache;
public MyService(IDistributedCache cache) {
_cache = cache;
}
public async Task<string> GetDataAsync(string key) {
var cachedData = await _cache.GetStringAsync(key);
if (cachedData == null) {
// Fetch data from source
var data = await FetchDataFromSource();
// Cache the data with options
var options = new DistributedCacheEntryOptions {
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30),
SlidingExpiration = TimeSpan.FromMinutes(5)
};
await _cache.SetStringAsync(key, data, options);
return data;
}
return cachedData;
}
}
Cache distribuído NCache
NCache é um cache distribuído em memória de código aberto desenvolvido nativamente em .NET e .NET Core. O NCache funciona localmente e configurado como um cluster de cache distribuído para um aplicativo ASP.NET Core em execução no Azure ou em outras plataformas de hospedagem.
Para instalar e configurar o NCache em sua máquina local, consulte Guia de Introdução para Windows (.NET e .NET Core).
Para configurar o NCache:
Instale NuGet de código aberto NCache.
Configure o cluster de cache em client.ncconf.
Adicione o seguinte código ao
Startup.ConfigureServices:services.AddNCacheDistributedCache(configuration => { configuration.CacheName = "demoClusteredCache"; configuration.EnableLogs = true; configuration.ExceptionsEnabled = true; });
Usar o cache distribuído
Para usar a IDistributedCache interface, solicite uma instância de IDistributedCache de qualquer construtor no aplicativo. A instância é fornecida por injeção de dependência (DI).
Quando o aplicativo de exemplo é iniciado, IDistributedCache é injetado no Startup.Configure. A hora atual é armazenada em cache usando IHostApplicationLifetime (para obter mais informações, consulte Host genérico: 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);
});
O aplicativo de exemplo injeta IDistributedCache no IndexModel para uso pela página Índice.
Cada vez que a página Índice é carregada, o cache é verificado para o tempo armazenado em cache no OnGetAsync. Se o tempo armazenado em cache não tiver expirado, o tempo será exibido. Se tiverem decorrido 20 segundos desde a última vez que a hora em cache foi acedida (a última vez que esta página foi carregada), a página apresenta Tempo em Cache Expirado.
Atualize imediatamente a hora armazenada em cache para a hora atual selecionando o botão Redefinir hora em cache . O botão aciona o método manipulador OnPostResetCachedTime.
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();
}
}
Note
Não há necessidade de usar um ciclo de vida Singleton ou Scoped para IDistributedCache instâncias (pelo menos para as implementações embutidas).
Você também pode criar uma IDistributedCache instância sempre que precisar de uma em vez de usar DI, mas criar uma instância no código pode tornar seu código mais difícil de testar e viola o Princípio de Dependências Explícitas.
Recommendations
Ao decidir qual implementação de IDistributedCache é a melhor para o seu aplicativo, considere o seguinte:
- Infraestrutura existente
- Requisitos de desempenho
- Cost
- Experiência de equipa
As soluções de cache geralmente dependem do armazenamento na memória para fornecer recuperação rápida de dados armazenados em cache, mas a memória é um recurso limitado e caro para expandir. Armazene apenas os dados mais usados em um cache.
Geralmente, um cache Redis fornece maior taxa de transferência e menor latência do que um cache do SQL Server. No entanto, o benchmarking geralmente é necessário para determinar as características de desempenho das estratégias de cache.
Quando o SQL Server é usado como um armazenamento de backup de cache distribuído, o uso do mesmo banco de dados para o cache e o armazenamento e recuperação de dados comuns do aplicativo podem afetar negativamente o desempenho de ambos. Recomendamos o uso de uma instância dedicada do SQL Server para o armazenamento de backup de cache distribuído.
Recursos adicionais
- Redis Cache no Azure
- Banco de Dados SQL no Azure
- Base de Dados do Azure para PostgreSQL
- ASP.NET Core IDistributedCache Provider para NCache em Web Farms (NCache no GitHub)
- Cache na memória no ASP.NET Core
- Detectar alterações com tokens de alteração no ASP.NET Core
- Cache de Resposta no ASP.NET Core
- Middleware de Cache de Resposta no ASP.NET Core
- Tag Helper de Cache em ASP.NET Core MVC
- auxiliar de tag de cache distribuído no ASP.NET Core
- Hospedar ASP.NET Core em uma web farm