Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Note
Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.
Warning
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.
Распределенный кэш — это кэш, общий для нескольких серверов приложений. Кэш обычно поддерживается как внешняя служба для серверов приложений, обращаюющихся к нему. Распределенный кэш может повысить производительность и масштабируемость приложения ASP.NET Core, особенно если облачная служба или ферма серверов размещает приложение.
Распределенный кэш имеет несколько преимуществ по сравнению с другими сценариями кэширования, в которых кэшированные данные хранятся на отдельных серверах приложений.
При распределении кэшированных данных данные:
- Последовательность (согласованность) между запросами к нескольким серверам.
- Выживает перезапуски сервера и развертывания приложений.
- Не использует локальную память.
Конфигурация распределенного кэша зависит от конкретного способа реализации. В этой статье описывается настройка распределенных кэшей SQL Server, Redis или Postgres. Кроме того, доступны не Microsoft реализации, например NCache (NCache на GitHub), Azure Cosmos DB и Postgres. Независимо от выбранной реализации приложение взаимодействует с кэшем IDistributedCache с помощью интерфейса.
Просмотреть или скачать образец кода (описание загрузки)
Warning
В этой статье используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".
Prerequisites
Добавьте ссылку на пакет для используемого поставщика распределенного кэша:
- Для распределенного кэша Redis Microsoft.Extensions.Caching.StackExchangeRedis.
- Для SQL Server, Microsoft.Extensions.Caching.SqlServer.
- Для Postgres, Microsoft.Extensions.Caching.Postgres.
- Для Azure Cosmos DB Microsoft.Extensions.Caching.Cosmos.
- Для распределенного кэша NCache. NCache.Microsoft.Extensions.Caching.OpenSource.
Использование интерфейса IDistributedCache
Интерфейс IDistributedCache предоставляет следующие методы для управления элементами в реализации распределенного кэша:
-
Get: GetAsyncпринимает строковый ключ и извлекает кэшированный элемент в виде
byte[]массива, если он найден в кэше. -
Set, SetAsync: добавляет элемент (в виде
byte[]массива) в кэш с помощью строкового ключа. - Refresh, RefreshAsync: обновляет элемент в кэше на основе ключа, сбросив время ожидания скольжения срока действия (если таковой имеется).
- Remove, RemoveAsync: удаляет элемент кэша на основе его строкового ключа.
Установка распределенных служб кэширования
Зарегистрируйте реализацию IDistributedCache в файле Program.cs . В этой статье описаны следующие реализации, предоставляемые платформой:
- Распределенный кэш Redis
- Распределенный кэш памяти
- Распределенный кэш SQL Server
- Распределенный кэш Postgres
- Распределенный кэш NCache
- Распределенный кэш Azure Cosmos DB
Распределенный кэш Redis
Распределенный кэш Redis обеспечивает оптимальную производительность и рекомендуется для рабочих приложений. Redis -это хранилище данных в памяти с открытым исходным кодом, которое часто используется в качестве распределенного кэша. Вы можете настроить Кэш Azure для Redis для размещенного в Azure приложения ASP.NET Core и использовать Кэш Azure для Redis для локальной разработки. Дополнительные сведения см. в статье "Просмотр рекомендаций по кэшу".
Приложение настраивает реализацию кэша с экземпляром RedisCache путем вызова AddStackExchangeRedisCache метода. Для кэширования выходных данных используйте AddStackExchangeRedisOutputCache метод.
Создайте экземпляр Кэш Azure для Redis.
Скопируйте основную строку подключения (строка подключения) StackExchange.Redis в Configuration.
For local development: сохраняйте строку подключения, используя Secret Manager.
For Azure: Сохраните строку подключения в безопасном хранилище, например Azure Key Vault.
Следующий код включает Кэш Azure для Redis:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
options.InstanceName = "SampleInstance";
});
В предыдущем коде предполагается, что основная строка подключения (StackExchange.Redis) сохраняется в конфигурации под именем ключа MyRedisConStr.
Дополнительные сведения см. в разделе Azure Managed Redis.
Обсуждение альтернативных подходов к локальному кэшу Redis см. в статье GitHub /dotnet/aspnetcore issue #19542.
Распределенный кэш памяти
Распределенный кэш памяти (AddDistributedMemoryCache) — это реализация, предоставляемая фреймворком, IDistributedCache в которой хранятся элементы в памяти. Однако распределенный кэш памяти не является фактическим распределенным кэшем. Экземпляр приложения хранит кэшированные элементы на сервере, на котором выполняется приложение.
Распределенный кэш памяти — это полезная реализация для сценариев разработки и тестирования. Это также полезно для одного сервера в рабочем сценарии, где потребление памяти не является проблемой. Реализация распределенного кэша памяти абстрагирует кэшированное хранилище данных. Он позволяет реализовать настоящую распределенную систему кэширования в будущем, если потребуется внедрение нескольких узлов или отказоустойчивость.
Пример приложения использует кэш распределенной памяти при запуске приложения в среде в Developmentфайле Program.cs .
builder.Services.AddDistributedMemoryCache();
Распределенный кэш SQL Server
Реализация распределенного кэша SQL Server (AddDistributedSqlServerCache) позволяет распределенному кэшу использовать базу данных SQL Server в качестве основного хранилища. Чтобы создать таблицу кэшированных элементов SQL Server в экземпляре SQL Server, можно использовать sql-cache средство. Средство создает таблицу с указанным именем и схемой.
Создайте таблицу в SQL Server, выполнив sql-cache create команду. Укажите экземпляр SQL Server (), базу данных (Data Source), схему (Initial Catalogнапример, dbo) и имя таблицы (например, TestCache):
dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
После успешного выполнения средства записывается сообщение:
Table and index were created successfully.
Таблица, созданная средством sql-cache, имеет следующую структуру:
Note
Приложение должно управлять значениями кэша с помощью экземпляра IDistributedCache, а не экземпляра SqlServerCache.
Пример приложения реализует SqlServerCache класс в среде, отличной от разработки (Development) в файле Program.cs :
builder.Services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString(
"DistCache_ConnectionString");
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Note
Свойства, такие как ConnectionString (и при необходимости, SchemaName и TableName), обычно хранятся вне системы контроля версий. Например, Secret Manager или appsettings.json или appsettings.{Environment}.json файл может хранить свойства. Строка подключения может содержать учетные данные, которые не должны попадать в системы управления версиями.
Дополнительные сведения см. в разделе SQL Database on Azure.
Распределенный кэш Postgres
База данных Azure для PostgreSQL может использоваться в качестве распределенного хранилища резервного кэша IDistributedCache через интерфейс. База данных Azure для PostgreSQL — это полностью управляемая, готовая к использованию ИИ база данных как услуга (DBaaS), созданная на основе ядра PostgreSQL с открытым исходным кодом. Проект поддерживает критически важные рабочие нагрузки с прогнозируемой производительностью, надежной безопасностью, высокой доступностью и простой масштабируемостью.
После установки пакета NuGet Microsoft.Extensions.Caching.Postgres настройте распределенный кэш следующим образом:
Зарегистрируйте службу.
using Microsoft.Extensions.DependencyInjection; var builder = WebApplication.CreateBuilder(args); // Register the 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();Используйте кэш.
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 the 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; } }
Распределенный кэш NCache
NCache — это распределенный кэш с открытым кодом в памяти, разработанный изначально в .NET. NCache работает как локально, так и настроен как кластер распределенного кэша для приложения ASP.NET Core, работающего в Azure или на других платформах размещения.
Сведения об установке и настройке NCache на локальном компьютере см. в руководстве по началу работы.
Чтобы настроить NCache, выполните приведенные действия.
Установите пакет NuGet NCache SDK, который поддерживает NCache с открытым исходным кодом для .NET Framework и приложений .NET Core.
Настройте кластер кэша в конфигурации клиента (файл client.ncconf ).
Добавьте следующий код в файл Program.cs :
builder.Services.AddNCacheDistributedCache(configuration =>
{
configuration.CacheName = "democache";
configuration.EnableLogs = true;
configuration.ExceptionsEnabled = true;
});
Распределенный кэш Azure Cosmos DB
Azure Cosmos DB можно настроить в ASP.NET Core в качестве поставщика состояний сеанса с помощью интерфейса IDistributedCache. Azure Cosmos DB — это полностью управляемая база данных NoSQL и реляционная база данных для современной разработки приложений, которая обеспечивает высокий уровень доступности, масштабируемость и низкую задержку доступа к данным для критически важных приложений.
После установки пакета NuGet Microsoft.Extensions.Caching.Cosmos настройте распределенный кэш Azure Cosmos DB. Вы можете использовать существующий клиент Azure Cosmos DB или создать новый, как описано в следующих разделах.
Для получения дополнительной информации см. расширение кэширования Microsoft с использованием Azure Cosmos DB, README-файл в репозитории GitHub для пакета NuGet.
Повторное использование существующего клиента
Самый простой способ настройки распределенного кэша — повторно использовать существующий клиент Azure Cosmos DB. В этом случае CosmosClient экземпляр не удаляется при удалении поставщика.
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
cacheOptions.CosmosClient = existingCosmosClient;
cacheOptions.CreateIfNotExists = true;
});
Создание нового клиента
Кроме того, создайте экземпляр нового клиента. В этом случае экземпляр объекта CosmosClient удаляется, когда удаляется поставщик.
services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
{
cacheOptions.ContainerName = Configuration["CosmosCacheContainer"];
cacheOptions.DatabaseName = Configuration["CosmosCacheDatabase"];
cacheOptions.ClientBuilder = new CosmosClientBuilder(Configuration["CosmosConnectionString"]);
cacheOptions.CreateIfNotExists = true;
});
Использование распределенного кэша
Чтобы использовать интерфейс IDistributedCache, запросите в приложении экземпляр IDistributedCache. Экземпляр предоставляется через внедрение зависимостей (DI).
При запуске IDistributedCache примера приложения экземпляр внедряется в файл Program.cs . Текущее время кэшируется с помощью IHostApplicationLifetime интерфейса. (Дополнительные сведения см. в разделе .NET универсальный хост: 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);
});
Пример приложения внедряет экземпляр IDistributedCache в объект IndexModel для использования на индексной странице.
Каждый раз, когда страница индекса загружается, кэш проверяется на кэшированное время с помощью OnGetAsync метода. Если кэшированное время не истекло, отображается время. Если 20 секунд истекло с момента последнего доступа к кэшированному времени (время последней загрузки этой страницы), на странице отображается сообщение с истекшим сроком действия кэшированного времени.
Немедленно обновите кэшированное время до текущего времени, выбрав параметр "Сброс кэшированного времени ". Это действие активирует метод обработчика 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();
}
}
Note
Для экземпляров со встроенной реализацией не требуется использовать одноэлементное или ограниченное время существования IDistributedCache .
Вы также можете создать IDistributedCache экземпляр, где бы вам ни понадобилось, а не использовать DI. Однако создание экземпляра в коде может сделать код более сложным для тестирования и нарушения принципа явных зависимостей.
Просмотр рекомендаций по кэшу
При принятии решения о том, какая реализация IDistributedCache интерфейса лучше всего подходит для вашего приложения, рассмотрите следующие моменты:
- Существующая инфраструктура
- Требования к производительности
- Cost
- Взаимодействие с командой
Решения кэширования обычно полагаются на хранилище в памяти для быстрого извлечения кэшированных данных, но память является ограниченным ресурсом и дорогостоящим для расширения. В кэше хранятся только часто используемые данные.
Для большинства приложений кэш Redis обеспечивает более высокую пропускную способность и низкую задержку, чем кэш SQL Server. Однако для определения характеристик производительности стратегий кэширования рекомендуется использовать тестовые показатели.
Если SQL Server является основным хранилищем для распределенного кэша, и кэш и приложение используют одну и ту же базу данных для хранения и извлечения данных, производительность может быть снижена. Рекомендуемый подход — использовать выделенный экземпляр SQL Server для хранилища резервной копии распределенного кэша.
Связанный контент
- Кэш Redis в Azure
- База данных SQL в Azure
- База данных Azure для PostgreSQL
- ASP.NET Core Поставщик IDistributedCache для NCache в веб-фермах (NCache на GitHub)
- Файл README репозитория для Microsoft.Extensions.Caching.Cosmos
- Обнаружение изменений с помощью маркеров изменений в ASP.NET Core
- Вспомогательный компонент тега кэша в ASP.NET Core MVC
- Вспомогательный компонент тега распределенного кэша в ASP.NET Core
- Размещение ASP.NET Core в веб-ферме
Распределенный кэш — это кэш, совместно используемый несколькими серверами приложений, как правило, в качестве внешней службы для серверов приложений, к которым он обращается. Распределенный кэш может повысить производительность и масштабируемость приложения ASP.NET Core, особенно если приложение размещается облачной службой или фермой серверов.
Распределенный кэш имеет несколько преимуществ по сравнению с другими сценариями кэширования, в которых кэшированные данные хранятся на отдельных серверах приложений.
При распределении кэшированных данных данные:
- Последовательность (согласованность) между запросами к нескольким серверам.
- Выживает перезапуски сервера и развертывания приложений.
- Не использует локальную память.
Конфигурация распределенного кэша зависит от конкретного способа реализации. В этой статье описывается настройка распределенных кэшей SQL Server, Redis и Postgres. Кроме того, доступны сторонние реализации, такие как NCache (NCache на GitHub). Независимо от выбранной реализации приложение взаимодействует с кэшем с помощью IDistributedCache интерфейса.
Просмотреть или скачать образец кода (описание загрузки)
Prerequisites
Добавьте ссылку на пакет для используемого поставщика распределенного кэша:
Для распределенного кэша Redis Microsoft.Extensions.Caching.StackExchangeRedis.
Для SQL Server, Microsoft.Extensions.Caching.SqlServer.
Для распределенного кэша NCache. NCache.Microsoft.Extensions.Caching.OpenSource.
-
Warning
В этой статье используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".
Интерфейс IDistributedCache
Интерфейс IDistributedCache предоставляет следующие методы для управления элементами в реализации распределенного кэша:
-
Get: GetAsyncпринимает строковый ключ и извлекает кэшированный элемент в виде
byte[]массива, если он найден в кэше. -
Set, SetAsync: добавляет элемент (в виде
byte[]массива) в кэш с помощью строкового ключа. - Refresh, RefreshAsync: обновляет элемент в кэше на основе ключа, сбрасывая интервал скользящей задержки действия (если он установлен).
- Remove, RemoveAsync: удаляет элемент кэша на основе его строкового ключа.
Установка распределенных служб кэширования
Регистрация реализации IDistributedCache в Program.cs. Предоставляемые платформой реализации, описанные в этом разделе, включают:
- Распределенный кэш Redis
- Кэш распределенной памяти
- Распределенный кэш SQL Server
- Распределенный кэш Postgres
- Распределенный кэш NCache
Распределенный кэш Redis
Мы рекомендуем использовать распределенный кэш Redis для рабочих приложений, так как это наиболее эффективно. Дополнительные сведения см. в разделе "Рекомендации".
Redis -это хранилище данных в памяти с открытым исходным кодом, которое часто используется в качестве распределенного кэша. Вы можете настроить кэш Redis Azure для размещенного в Azure приложения ASP.NET Core и использовать кэш Redis Azure для локальной разработки.
Приложение настраивает реализацию кэша с помощью экземпляра RedisCache (AddStackExchangeRedisCache).
- Создайте Кэш Azure для Redis.
- Скопируйте основную строку подключения (StackExchange.Redis) в Конфигурацию.
- Локальная разработка: Сохранение строки подключения с помощью диспетчера секретов.
- Azure: сохраните строку подключения в безопасном хранилище, например: Azure Key Vault
Следующий код включает Кэш Azure для Redis:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
options.InstanceName = "SampleInstance";
});
Предыдущий код предполагает, что основная строка подключения (StackExchange.Redis) была сохранена в конфигурации с именем ключа MyRedisConStr.
Для получения дополнительной информации, см. Кэш Azure для Redis.
См этот запрос на GitHub для обсуждения альтернативных подходов к локальному кэшу Redis.
Кэш распределенной памяти
Кэш распределенной памяти (AddDistributedMemoryCache) — это реализация, предоставляемая фреймворком, в IDistributedCache которой хранятся элементы в памяти. Кэш распределенной памяти не является фактическим распределенным кэшем. Кэшированные элементы хранятся экземпляром приложения на сервере, на котором выполняется приложение.
Кэш распределенной памяти — это полезная реализация:
- В сценариях разработки и тестирования.
- Если один сервер используется в рабочей среде, а потребление памяти не является проблемой. Реализация распределенного кэша памяти абстрагирует кэшированное хранилище данных. Он позволяет реализовать истинное распределенное решение кэширования в будущем, при необходимости нескольких узлов или отказоустойчивости.
Пример приложения использует кэш распределенной памяти при запуске приложения в Development среде:Program.cs
builder.Services.AddDistributedMemoryCache();
Распределенный кэш SQL Server
Реализация распределенного кэша на SQL Server (AddDistributedSqlServerCache) позволяет распределенному кэшу использовать базу данных SQL Server в качестве хранилища. Чтобы создать таблицу кэшированных элементов SQL Server в экземпляре SQL Server, можно использовать инструмент sql-cache. Средство создает таблицу с указанным именем и схемой.
Создайте таблицу в SQL Server, выполнив sql-cache create команду. Укажите экземпляр SQL Server (), базу данных (Data Source), схему (Initial Catalogнапример, dbo) и имя таблицы (например, TestCache):
dotnet sql-cache create "Data Source=(localdb)/MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
В журнал записывается сообщение, указывающее, что средство выполнено успешно:
Table and index were created successfully.
Таблица, созданная средством sql-cache, имеет следующую схему:
Note
Приложение должно управлять значениями кэша с помощью экземпляра IDistributedCache, а не SqlServerCache.
Пример приложения реализует SqlServerCache в не-Development среде Program.cs.
builder.Services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString(
"DistCache_ConnectionString");
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Note
A ConnectionString (и опционально, SchemaName и TableName) обычно хранятся вне системы управления версиями (например, хранятся Secret Manager или в appsettings.json/appsettings.{Environment}.json файлах). Строка подключения может содержать учетные данные, которые должны храниться вне систем управления версиями.
Распределенный кэш Postgres
База данных Azure для PostgreSQL может использоваться в качестве распределенного хранилища резервного кэша IDistributedCache через интерфейс. База данных Azure для PostgreSQL — это полностью управляемая, готовая к использованию ИИ база данных как услуга (DBaaS), созданная на основе ядра PostgreSQL с открытым исходным кодом, предназначенная для поддержки критически важных рабочих нагрузок с прогнозируемой производительностью, надежной безопасностью, высокой доступностью и простой масштабируемостью.
После установки пакета NuGet Microsoft.Extensions.Caching.Postgres настройте распределенный кэш следующим образом:
- Регистрация службы
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();
- Использование кэша
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;
}
}
Распределенный кэш NCache
NCache — это открытый код распределенный кэш в памяти, разработанный изначально в .NET и .NET Core. NCache работает как локально, так и настроен как кластер распределенного кэша для приложения ASP.NET Core, работающего в Azure или на других платформах размещения.
Сведения об установке и настройке NCache на локальном компьютере см. в руководстве по началу работы с Windows (.NET и .NET Core).
Чтобы настроить NCache, выполните приведенные действия.
- Установите пакет NuGet с открытым исходным кодом NCache.
- Настройте кластер кэша в client.ncconf.
- Добавьте следующий код в
Program.cs:
builder.Services.AddNCacheDistributedCache(configuration =>
{
configuration.CacheName = "democache";
configuration.EnableLogs = true;
configuration.ExceptionsEnabled = true;
});
Использование распределенного кэша
Чтобы использовать интерфейс IDistributedCache, запросите в приложении экземпляр IDistributedCache. Экземпляр предоставляется инъекцией зависимостей (DI).
При запуске приложения-примера, IDistributedCache вставляется в Program.cs. Текущее время кэшируется с помощью IHostApplicationLifetime (дополнительные сведения см. в разделе Generic 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);
});
Примерное приложение внедряет IDistributedCache в IndexModel для использования на странице индекса.
Каждый раз при загрузке главной страницы кэш проверяется на сохраненное в нем время.OnGetAsync Если кэшированное время не истекло, отображается время. Если 20 секунд истекло с момента последнего доступа к кэшированному времени (время последней загрузки этой страницы), на странице отображается срок действия кэшированного времени.
Немедленно обновите кэшированное время до текущего времени, нажав кнопку "Сброс кэшированного времени ". Кнопка активирует метод обработчика 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();
}
}
Нет необходимости использовать одноэлементное или ограниченное время существования для IDistributedCache экземпляров со встроенными реализациями.
Вы также можете создать IDistributedCache экземпляр там, где он может вам понадобиться, а не использовать DI, но создание экземпляра в коде может усложнить тестирование и нарушает Принцип явных зависимостей.
Recommendations
При принятии решения о том, какая реализация IDistributedCache лучше всего подходит для вашего приложения, рассмотрите следующее:
- Существующая инфраструктура
- Требования к производительности
- Cost
- Взаимодействие с командой
Решения кэширования обычно полагаются на хранилище в памяти для быстрого извлечения кэшированных данных, но память является ограниченным ресурсом и дорогостоящим для расширения. В кэше хранятся только часто используемые данные.
Для большинства приложений кэш Redis обеспечивает более высокую пропускную способность и низкую задержку, чем кэш SQL Server. Однако для определения характеристик производительности стратегий кэширования рекомендуется использовать тестовые показатели.
Если SQL Server используется в качестве поддерживающего хранилища для распределенного кэша, использование одной и той же базы данных для кэша и для обычного сохранения и получения данных приложения может негативно сказаться на производительности обоих. Рекомендуется использовать выделенный экземпляр SQL Server для резервного хранилища распределенного кэша.
Дополнительные ресурсы
- Кэш Redis в Azure
- База данных SQL в Azure
- База данных Azure для PostgreSQL
- ASP.NET Core Поставщик IDistributedCache для NCache в веб-фермах (NCache на GitHub)
- Кэширование в памяти в ASP.NET Core
- Обнаружение изменений с помощью маркеров изменений в ASP.NET Core
- Кэширование ответов в ASP.NET Core
- Промежуточное программное обеспечение для кэширования ответов в ASP.NET Core
- Вспомогательный компонент тега кэша в ASP.NET Core MVC
- Вспомогательный компонент тега распределенного кэша в ASP.NET Core
- Размещение ASP.NET Core на веб-ферме
Распределенный кэш — это кэш, совместно используемый несколькими серверами приложений, как правило, в качестве внешней службы для серверов приложений, к которым он обращается. Распределенный кэш может повысить производительность и масштабируемость приложения ASP.NET Core, особенно если приложение размещается облачной службой или фермой серверов.
Распределенный кэш имеет несколько преимуществ по сравнению с другими сценариями кэширования, в которых кэшированные данные хранятся на отдельных серверах приложений.
При распределении кэшированных данных они:
- Сохраняет целостность (последовательность) между запросами к нескольким серверам.
- Выживает перезапуски сервера и развертывания приложений.
- Не использует локальную память.
Конфигурация распределенного кэша зависит от конкретной реализации. В этой статье описывается настройка распределенных кэшей SQL Server, Redis и Postgres. Кроме того, доступны сторонние реализации, такие как NCache (NCache на GitHub). Независимо от выбранной реализации приложение взаимодействует с кэшем с помощью IDistributedCache интерфейса.
Просмотреть или скачать образец кода (описание загрузки)
Prerequisites
Чтобы использовать распределенный кэш SQL Server, добавьте ссылку на пакет Microsoft.Extensions.Caching.SqlServer .
Чтобы использовать распределенный кэш Redis, добавьте ссылку на пакет Microsoft.Extensions.Caching.StackExchangeRedis .
Чтобы использовать распределенный кэш Postgres, добавьте ссылку на пакет Microsoft.Extensions.Caching.Postgres .
Чтобы использовать распределенный кэш NCache, добавьте ссылку на пакет NCache.Microsoft.Extensions.Caching.OpenSource .
Интерфейс IDistributedCache
Интерфейс IDistributedCache предоставляет следующие методы для управления элементами в реализации распределенного кэша:
-
Get: GetAsyncпринимает строковый ключ и извлекает кэшированный элемент в виде
byte[]массива, если он найден в кэше. -
Set, SetAsync: добавляет элемент (в виде
byte[]массива) в кэш с помощью строкового ключа. - Refresh, RefreshAsync: обновляет элемент в кэше на основе ключа, сбросив время ожидания скольжения срока действия (если таковой имеется).
- Remove, RemoveAsync: удаляет элемент кэша на основе его строкового ключа.
Установка распределенных служб кэширования
Зарегистрируйте реализацию IDistributedCache в Startup.ConfigureServices. Предоставляемые платформой реализации, описанные в этом разделе, включают:
- Кэш распределенной памяти
- Распределенный кэш SQL Server
- Распределенный кэш Redis
- Распределенный кэш Postgres
- Распределенный кэш NCache
Кэш распределенной памяти
Кэш распределенной памяти (AddDistributedMemoryCache) — это реализация, предоставляемая платформой, IDistributedCache, которая хранит элементы в памяти. Кэш распределенной памяти не является фактическим распределенным кэшем. Кэшированные элементы хранятся экземпляром приложения на сервере, на котором выполняется приложение.
Кэш распределенной памяти — это полезная реализация:
- В сценариях разработки и тестирования.
- Если один сервер используется в рабочей среде, а потребление памяти не является проблемой. Реализация распределенного кэша памяти абстрагирует кэшированное хранилище данных. Он позволяет реализовать настоящую распределенную систему кэширования в будущем, если потребуется внедрение нескольких узлов или отказоустойчивость.
Пример приложения использует кэш распределенной памяти при запуске приложения в Development среде:Startup.ConfigureServices
services.AddDistributedMemoryCache();
Распределенный кэш SQL Server
Реализация распределённого кэша SQL Server (AddDistributedSqlServerCache) позволяет распределённому кэшу использовать базу данных SQL Server в качестве резервного хранилища. Чтобы создать таблицу кэшированных элементов SQL Server в экземпляре SQL Server, можно использовать sql-cache средство. Средство создает таблицу с указанным именем и схемой.
Создайте таблицу в SQL Server, выполнив sql-cache create команду. Укажите экземпляр SQL Server (), базу данных (Data Source), схему (Initial Catalogнапример, dbo) и имя таблицы (например, TestCache):
dotnet sql-cache create "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DistCache;Integrated Security=True;" dbo TestCache
В журнал записывается сообщение, указывающее, что средство выполнено успешно:
Table and index were created successfully.
Таблица, созданная средством sql-cache, имеет следующую структуру:
Note
Приложение должно управлять значениями кэша с помощью экземпляра IDistributedCache, а не SqlServerCache.
Пример приложения реализует SqlServerCache в не-Development среде Startup.ConfigureServices.
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString =
_config["DistCache_ConnectionString"];
options.SchemaName = "dbo";
options.TableName = "TestCache";
});
Note
A ConnectionString (и при необходимости, SchemaName и TableName) обычно хранятся вне системы контроля версий (например, в Secret Manager или в файлах appsettings.json/appsettings.{Environment}.json). Строка подключения может содержать учетные данные, которые должны храниться вне систем контроля версий.
Распределенный кэш Redis
Redis -это хранилище данных в памяти с открытым исходным кодом, которое часто используется в качестве распределенного кэша. Вы можете настроить кэш Redis Azure для размещенного в Azure приложения ASP.NET Core и использовать кэш Redis Azure для локальной разработки.
Приложение настраивает реализацию кэша с помощью экземпляра RedisCache (AddStackExchangeRedisCache).
- Создайте Кэш Azure для Redis.
- Скопируйте основную строку подключения (StackExchange.Redis) в Configuration.
- Локальная разработка: Сохраните строку подключения с помощью диспетчера секретов.
- Azure: сохраните строку подключения в защищённом хранилище, таком как Azure Key Vault
Следующий код включает Кэш Azure для Redis:
public void ConfigureServices(IServiceCollection services)
{
if (_hostContext.IsDevelopment())
{
services.AddDistributedMemoryCache();
}
else
{
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = _config["MyRedisConStr"];
options.InstanceName = "SampleInstance";
});
}
services.AddRazorPages();
}
Предыдущий код предполагает, что основная строка подключения (StackExchange.Redis) была сохранена в конфигурации с именем ключа MyRedisConStr.
Для получения дополнительной информации см. Кэш Azure для Redis.
См. этот вопрос в GitHub для обсуждения альтернативных подходов к локальному кэшу Redis.
Распределенный кэш Postgres
База данных Azure для PostgreSQL может использоваться в качестве распределенного хранилища резервного кэша IDistributedCache через интерфейс. База данных Azure для PostgreSQL — это полностью управляемая, готовая к использованию ИИ база данных как услуга (DBaaS), созданная на основе ядра PostgreSQL с открытым исходным кодом, предназначенная для поддержки критически важных рабочих нагрузок с прогнозируемой производительностью, надежной безопасностью, высокой доступностью и простой масштабируемостью.
После установки пакета NuGet Microsoft.Extensions.Caching.Postgres настройте распределенный кэш следующим образом:
- Регистрация службы
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();
- Использование кэша
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;
}
}
Распределенный кэш NCache
NCache — это открытый код распределенный кэш в памяти, разработанный изначально в .NET и .NET Core. NCache работает как локально, так и настроен как кластер распределенного кэша для приложения ASP.NET Core, работающего в Azure или на других платформах размещения.
Сведения об установке и настройке NCache на локальном компьютере см. в руководстве по началу работы с Windows (.NET и .NET Core).
Чтобы настроить NCache, выполните приведенные действия.
Установите пакет NuGet с открытым исходным кодом NCache.
Настройте кластер кэша в client.ncconf.
Добавьте следующий код в
Startup.ConfigureServices:services.AddNCacheDistributedCache(configuration => { configuration.CacheName = "demoClusteredCache"; configuration.EnableLogs = true; configuration.ExceptionsEnabled = true; });
Использование распределенного кэша
Для использования интерфейса IDistributedCache, получите экземпляр IDistributedCache из любого конструктора в приложении. Экземпляр предоставляется через внедрение зависимостей (DI).
При запуске приложения-примера, IDistributedCache вставляется в Startup.Configure. Текущее время кэшируется с помощью IHostApplicationLifetime (дополнительные сведения см. в разделе Generic 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);
});
Примерное приложение внедряет IDistributedCache в IndexModel для использования на странице индекса.
Каждый раз при загрузке главной страницы кэш проверяется на сохраненное в нем время.OnGetAsync Если кэшированное время не истекло, отображается время. Если 20 секунд истекло с момента последнего доступа к кэшированному времени (время последней загрузки этой страницы), на странице отображается срок действия кэшированного времени.
Немедленно обновите кэшированное время до текущего времени, нажав кнопку "Сброс кэшированного времени ". Кнопка активирует метод обработчика 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
Необязательно использовать время жизни Singleton или Scoped для экземпляров IDistributedCache (по крайней мере, для встроенных реализаций).
Вы также можете создать IDistributedCache экземпляр там, где он может вам понадобиться, а не использовать DI, но создание экземпляра в коде может усложнить тестирование и нарушает Принцип явных зависимостей.
Recommendations
При принятии решения о том, какая реализация IDistributedCache лучше всего подходит для вашего приложения, рассмотрите следующее:
- Существующая инфраструктура
- Требования к производительности
- Cost
- Взаимодействие с командой
Решения кэширования обычно полагаются на хранилище в памяти для быстрого извлечения кэшированных данных, но память является ограниченным ресурсом и дорогостоящим для расширения. В кэше хранятся только часто используемые данные.
Как правило, кэш Redis обеспечивает более высокую пропускную способность и меньшую задержку, чем кэш SQL Server. Однако для определения характеристик производительности стратегий кэширования обычно требуется тестирование.
Если SQL Server используется в качестве поддерживающего хранилища для распределенного кэша, использование одной и той же базы данных для кэша и для обычного сохранения и получения данных приложения может негативно сказаться на производительности обоих. Рекомендуется использовать выделенный экземпляр SQL Server для резервного хранилища распределенного кэша.
Дополнительные ресурсы
- Кэш Redis в Azure
- База данных SQL в Azure
- База данных Azure для PostgreSQL
- ASP.NET Core Поставщик IDistributedCache для NCache в веб-фермах (NCache на GitHub)
- Кэширование в памяти в ASP.NET Core
- Обнаружение изменений с помощью маркеров изменений в ASP.NET Core
- Кэширование ответов в ASP.NET Core
- Промежуточное программное обеспечение для кэширования ответов в ASP.NET Core
- Вспомогательный компонент тега кэша в ASP.NET Core MVC
- Вспомогательный компонент тега распределенного кэша в ASP.NET Core
- Размещение ASP.NET Core в веб-ферме
ASP.NET Core