Общие сведения о кэшировании в ASP.NET Core

Примечание.

Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.

Авторы: Рик Андерсон (Rick Anderson) и Том Дайкстра (Tom Dykstra)

В этой статье представлен обзор кэширования в ASP.NET Core с введением во внутрипроцессное, распределенное, гибридное, кэширование ответов и кэширование данных на выходе.

Кэширование в памяти

Кэширование в памяти использует память сервера для хранения кэшированных данных. Этот тип кэширования подходит для одного сервера или нескольких серверов, использующих сходство сеансов. Привязка сеанса также называется липкими сеансами. Сходство сеансов означает, что запросы от клиента всегда направляются на тот же сервер для обработки.

Дополнительные сведения см. в разделе «Кэш в памяти» в ASP.NET Core и Устранение проблем с привязкой сеансов Шлюза приложений Azure.

Распределенный кэш

Используйте распределенный кэш для хранения данных, когда приложение размещается в облачной или серверной ферме. Кэш используется на серверах, обрабатывающих запросы. Клиент может отправить запрос, который обрабатывается любым сервером в группе, когда кэшированные данные для клиента доступны. ASP.NET Core работает с распределенными кэшами SQL Server, Redis, Postgres и NCache .

Дополнительные сведения см. в статье Распределенное кэширование в ASP.NET Core.

HybridCache

HybridCache API устраняет разрывы между API IDistributedCache и IMemoryCache. HybridCache — абстрактный класс с реализацией по умолчанию, которая обрабатывает большинство аспектов сохранения в кэше и извлечения из кэша.

Функции HybridCache

HybridCache предоставляет следующие функции, недоступные для других API:

  • Унифицированный API для кэширования как внутри процесса, так и для внепроцессного кэширования.

    HybridCache предназначен для замены существующего использования IDistributedCache и IMemoryCache и предоставляет простой интерфейс API для добавления нового кода кеширования. Если у приложения есть IDistributedCache реализация, HybridCache служба использует ее для дополнительного кэширования. Эта двухуровневая стратегия кэширования позволяет HybridCache обеспечить скорость кэша в памяти и устойчивость распределенного или постоянного кэша.

  • Защита от паники.

    Атака кеша происходит, когда часто используемая запись кеша становится недействительной, и слишком много запросов пытаются одновременно заполнить её заново. HybridCache объединяет параллельные операции, что гарантирует, что все запросы для заданного ответа ожидают первого запроса для заполнения кэша.

  • Настраиваемая сериализация.

    Сериализация настраивается как часть регистрации службы, поддерживается использование специфических для типа и обобщенных сериализаторов через методы WithSerializer и WithSerializerFactory, которые связываются с вызовом AddHybridCache. По умолчанию служба внутренне обрабатывает типы string и byte[], и использует пространство имен System.Text.Json для всего остального. HybridCache можно настроить для других типов сериализаторов, таких как protobuf или XML.

Чтобы увидеть относительную простоту HybridCache API, сравните код, который использует его для кода, который использует IDistributedCache. Вот пример того, как выглядит использование IDistributedCache:

public class SomeService(IDistributedCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync
        (string name, int id, CancellationToken token = default)
    {
        var key = $"someinfo:{name}:{id}"; // Unique key for this combination.
        var bytes = await cache.GetAsync(key, token); // Try to get from cache.
        SomeInformation info;
        if (bytes is null)
        {
            // Cache miss; get the data from the real source.
            info = await SomeExpensiveOperationAsync(name, id, token);

            // Serialize and cache it.
            bytes = SomeSerializer.Serialize(info);
            await cache.SetAsync(key, bytes, token);
        }
        else
        {
            // Cache hit; deserialize it.
            info = SomeSerializer.Deserialize<SomeInformation>(bytes);
        }
        return info;
    }

    // This is the work we're trying to cache.
    private async Task<SomeInformation> SomeExpensiveOperationAsync(string name, int id,
        CancellationToken token = default)
    { /* ... */ }
}

В коде демонстрируется значительный объем работы, чтобы каждый раз все сделать правильно, включая такие аспекты, как сериализация. Кроме того, в сценарии "пропустить кэш" может возникнуть несколько параллельных потоков. Эти потоки могут получать пропущенные кэши, получать все базовые данные, сериализовать их и отправлять данные в кэш.

Ниже приведен эквивалентный код, использующий HybridCache API:

public class SomeService(HybridCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync
        (string name, int id, CancellationToken token = default)
    {
        return await cache.GetOrCreateAsync(
            $"someinfo:{name}:{id}", // Unique key for this entry.
            async cancel => await SomeExpensiveOperationAsync(name, id, cancel),
            token: token
        );
    }
}

Код стал проще, и библиотека обеспечивает защиту от лавины запросов и другие функции, которые недоступны в интерфейсе IDistributedCache.

Совместимость

Библиотека HybridCache поддерживает старые среды выполнения .NET, включая .NET Framework 4.7.2 и .NET Standard 2.0.

Дополнительные сведения

Дополнительные сведения см. на следующих ресурсах:

кэширование ответов;

Промежуточное программное обеспечение для кэширования ответов включает кэширование ответов сервера на основе заголовков HTTP Cache-Control.

  • Поведение кэширования реализует стандартную семантику кэширования HTTP.

  • Кэширование основано на заголовках кэша HTTP, аналогичных методу, используемому прокси-серверами.

  • Эта форма кэширования полезна для общедоступных запросов GET или HEAD API от клиентов, в которых выполнены условия кэширования .

  • Для приложений пользовательского интерфейса, таких как Razor Pages, кэширование ответов обычно не является полезным. Браузеры обычно задают заголовки запросов, которые предотвращают кэширование.

    Кэширование вывода (доступно в .NET 7 и более поздних версиях) является лучшим подходом для приложений пользовательского интерфейса. В этом сценарии конфигурация определяет, что кэшировать независимо от заголовков HTTP.

Чтобы проверить кэширование ответов, используйте Fiddler или другое средство, которое может явно задать заголовки запросов. Для тестирования кэширования предпочтительнее явно задать заголовки. Дополнительные сведения см. в разделе "Устранение неполадок промежуточного слоя кэширования ответов>".

Дополнительные сведения см. в статье Кэширование ответов в ASP.NET Core.

Кэширование вывода

Промежуточное ПО для кэширования выходных данных позволяет кэширование HTTP-ответов. Кэширование выходных данных отличается от кэширования ответов следующими способами:

  • Поведение кэширования настраивается на сервере.

    Поведение кэширования ответов определяется по заголовкам HTTP. Например, при просмотре веб-сайта с помощью Chrome или Microsoft Edge браузер автоматически отправляет заголовок Cache-control: max-age=0. Этот заголовок эффективно отключает кэширование ответов, так как сервер следует указаниям, предоставленным клиентом. Новый ответ возвращается для каждого запроса, даже если сервер имеет свежий кэшированный ответ. При кэшировании выходных данных клиент не переопределяет поведение кэширования, настроенного на сервере.

  • Среда хранилища кэша расширяема.

    Память используется по умолчанию. Кэширование ответов ограничено памятью.

  • Вы можете программным способом отключить выбранные записи кэша.

    Кэширование ответов зависит от заголовков HTTP, что оставляет вас с небольшими возможностями для аннулирования записей кэша.

  • Блокировка ресурсов снижает риск наплыва обращений к кэшу и эффекта гремящего стада.

    Атака кеша происходит, когда часто используемая запись кеша становится недействительной, и слишком много запросов пытаются одновременно заполнить её заново. Грома стада аналогична: всплеск запросов на тот же ответ, который еще не находится в записи кэша. Блокировка ресурсов гарантирует, что все запросы для заданного ответа ожидают первого запроса, чтобы заполнить кэш. Кэширование ответов не имеет функции блокировки ресурсов.

  • Повторная проверка кэша сводит к минимуму использование пропускной способности.

    Проверка валидности кэша означает, что сервер может возвращать код состояния HTTP 304 Not Modified вместо кэшированного текста ответа. Этот код состояния сообщает клиенту, что ответ на запрос не изменяется от того, что было получено ранее. Кэширование ответов не выполняет проверку актуальности кэша.

Для получения дополнительных сведений см. Промежуточное программное обеспечение кэширования выходных данных в ASP.NET Core.

Вспомогательный модуль тегирования для кэша

Кэшируйте содержимое представления MVC или Razor страницы с помощью помощника тега кэша. Вспомогательный элемент для тегов кэша использует кэширование в памяти для хранения данных.

Дополнительные сведения см. в Вспомогательный тег кеша в ASP.NET Core MVC.

Вспомогательная функция тега распределенного кэша

Кэшируйте содержимое из представления MVC или Razor страницы в сценариях распределённого облака или веб-фермы с помощью вспомогательного тега распределённого кеша. Помощник по тегу распределенного кэша использует SQL Server, Redis или NCache для хранения данных.

Для получения дополнительной информации см. Помощник тегов распределенного кэша в ASP.NET Core.

Кэширование в памяти

Кэширование в памяти использует память сервера для хранения кэшированных данных. Этот тип кэширования подходит для одного сервера или нескольких серверов, использующих сходство сеансов. Привязка сеанса также называется липкими сеансами. Сходство сеансов означает, что запросы от клиента всегда направляются на тот же сервер для обработки.

Дополнительные сведения см. в разделе «Кэш в памяти» в ASP.NET Core и Устранение проблем с привязкой сеансов Шлюза приложений Azure.

Распределенный кэш

Используйте распределенный кэш для хранения данных, когда приложение размещается в облачной или серверной ферме. Кэш используется на серверах, обрабатывающих запросы. Клиент может отправить запрос, который обрабатывается любым сервером в группе, если кэшированные данные для клиента доступны. ASP.NET Core работает с распределенными кэшами SQL Server, Redis, Postgres и NCache .

Дополнительные сведения см. в статье Распределенное кэширование в ASP.NET Core.

HybridCache

HybridCache API устраняет разрывы между API IDistributedCache и IMemoryCache. HybridCache — абстрактный класс с реализацией по умолчанию, которая обрабатывает большинство аспектов сохранения в кэше и извлечения из кэша.

Функции HybridCache

HybridCache предоставляет следующие функции, недоступные для других API:

  • Унифицированный API для кэширования как внутри процесса, так и для внепроцессного кэширования.

    HybridCache предназначен для замены существующего использования IDistributedCache и IMemoryCache и предоставляет простой интерфейс API для добавления нового кода кеширования. Если у приложения есть IDistributedCache реализация, HybridCache служба использует ее для дополнительного кэширования. Эта двухуровневая стратегия кэширования позволяет HybridCache обеспечить скорость кэша в памяти и устойчивость распределенного или постоянного кэша.

  • Защита от паники.

    Атака кеша происходит, когда часто используемая запись кеша становится недействительной, и слишком много запросов пытаются одновременно заполнить её заново. HybridCache объединяет параллельные операции, что гарантирует, что все запросы для заданного ответа ожидают первого запроса для заполнения кэша.

  • Настраиваемая сериализация.

    Сериализация настраивается как часть регистрации службы, поддерживается использование специфических для типа и обобщенных сериализаторов через методы WithSerializer и WithSerializerFactory, которые связываются с вызовом AddHybridCache. По умолчанию служба внутренне обрабатывает типы string и byte[], и использует пространство имен System.Text.Json для всего остального. HybridCache можно настроить для других типов сериализаторов, таких как protobuf или XML.

Чтобы увидеть относительную простоту HybridCache API, сравните код, который использует его для кода, который использует IDistributedCache. Вот пример того, как выглядит использование IDistributedCache:

public class SomeService(IDistributedCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync
        (string name, int id, CancellationToken token = default)
    {
        var key = $"someinfo:{name}:{id}"; // Unique key for this combination.
        var bytes = await cache.GetAsync(key, token); // Try to get from cache.
        SomeInformation info;
        if (bytes is null)
        {
            // Cache miss; get the data from the real source.
            info = await SomeExpensiveOperationAsync(name, id, token);

            // Serialize and cache it.
            bytes = SomeSerializer.Serialize(info);
            await cache.SetAsync(key, bytes, token);
        }
        else
        {
            // Cache hit; deserialize it.
            info = SomeSerializer.Deserialize<SomeInformation>(bytes);
        }
        return info;
    }

    // This is the work we're trying to cache.
    private async Task<SomeInformation> SomeExpensiveOperationAsync(string name, int id,
        CancellationToken token = default)
    { /* ... */ }
}

В коде демонстрируется значительный объем работы, чтобы каждый раз все сделать правильно, включая такие аспекты, как сериализация. Кроме того, в сценарии "пропустить кэш" может возникнуть несколько параллельных потоков. Эти потоки могут получать пропущенные кэши, получать все базовые данные, сериализовать их и отправлять данные в кэш.

Ниже приведен эквивалентный код, использующий HybridCache API:

public class SomeService(HybridCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync
        (string name, int id, CancellationToken token = default)
    {
        return await cache.GetOrCreateAsync(
            $"someinfo:{name}:{id}", // Unique key for this entry.
            async cancel => await SomeExpensiveOperationAsync(name, id, cancel),
            token: token
        );
    }
}

Код стал проще, и библиотека обеспечивает защиту от лавины запросов и другие функции, которые недоступны в интерфейсе IDistributedCache.

Совместимость

Библиотека HybridCache поддерживает старые среды выполнения .NET, включая .NET Framework 4.7.2 и .NET Standard 2.0.

Дополнительные сведения

Дополнительные сведения см. на следующих ресурсах:

Вспомогательный модуль тегирования для кэша

Кэшируйте содержимое представления MVC или Razor страницы с помощью помощника тега кэша. Вспомогательный элемент для тегов кэша использует кэширование в памяти для хранения данных.

Дополнительные сведения см. в Вспомогательный тег кеша в ASP.NET Core MVC.

Вспомогательная функция тега распределенного кэша

Кэшируйте содержимое из представления MVC или Razor страницы в сценариях распределённого облака или веб-фермы с помощью вспомогательного тега распределённого кеша. Помощник по тегу распределенного кэша использует SQL Server, Redis или NCache для хранения данных.

Для получения дополнительной информации см. Помощник тегов распределенного кэша в ASP.NET Core.

кэширование ответов;

Промежуточное ПО для кэширования ответов позволяет кэширование ответов сервера с использованием заголовков HTTP Cache-Control.

  • Поведение кэширования реализует стандартную семантику кэширования HTTP.

  • Кэширование основано на заголовках кэша HTTP, аналогичных методу, используемому прокси-серверами.

  • Эта форма кэширования полезна для общедоступных запросов GET или HEAD API от клиентов, в которых выполнены условия кэширования .

  • Для приложений пользовательского интерфейса, таких как Razor Pages, кэширование ответов обычно не является полезным. Браузеры обычно задают заголовки запросов, которые предотвращают кэширование.

    Кэширование выводных данных (доступно в .NET 7 и более поздних версиях) — это лучший подход для приложений с интерфейсом пользователя. В этом сценарии конфигурация определяет, что кэшировать независимо от заголовков HTTP.

Чтобы проверить кэширование ответов, используйте Fiddler или другое средство, которое может явно задать заголовки запросов. Для тестирования кэширования предпочтительнее явно задать заголовки. Для получения дополнительной информации см. раздел "Устранение неполадок в промежуточном программном слое кэширования ответов>".

Кэширование вывода

Промежуточное ПО для кэширования выходных данных позволяет кэширование HTTP-ответов. Кэширование выходных данных отличается от кэширования ответов следующими способами:

  • Поведение кэширования настраивается на сервере.

    Поведение кэширования ответа определяется заголовками HTTP. Например, при посещении веб-сайта с chrome или Edge браузер автоматически отправляет Cache-control: max-age=0 заголовок. Этот заголовок фактически отключает кэширование ответов, так как сервер следует указаниям, предоставленным клиентом. Новый ответ возвращается для каждого запроса, даже если сервер имеет свежий кэшированный ответ. При кэшировании выходных данных клиент не переопределяет поведение кэширования, настроенного на сервере.

  • Среда хранилища кэша расширяема.

    Память используется по умолчанию. Кэширование ответов ограничено памятью.

  • Вы можете программным способом отключить выбранные записи кэша.

    Зависимость кэширования ответов от заголовков HTTP предоставляет вам ограниченные возможности для аннулирования записей кэша.

  • Блокировка ресурсов снижает риск наплыва обращений к кэшу и эффекта гремящего стада.

    Атака кеша происходит, когда часто используемая запись кеша становится недействительной, и слишком много запросов пытаются одновременно заполнить её заново. Грома стада аналогична: всплеск запросов на тот же ответ, который еще не находится в записи кэша. Блокировка ресурсов гарантирует, что все запросы для заданного ответа ожидают первого запроса, чтобы заполнить кэш. Кэширование ответов не имеет функции блокировки ресурсов.

  • Повторная проверка кэша сводит к минимуму использование пропускной способности.

    Повторная проверка кэша означает, что сервер может возвращать 304 Not Modified код состояния HTTP вместо кэшированного текста ответа. Этот код состояния сообщает клиенту, что ответ на запрос не изменяется от того, что было получено ранее. Кэширование ответов не выполняет проверку актуальности кэша.

Кэширование в памяти

Кэширование в памяти использует память сервера для хранения кэшированных данных. Этот тип кэширования подходит для одного сервера или нескольких серверов, использующих сходство сеансов. Привязка сеанса также называется липкими сеансами. Сходство сеансов означает, что запросы от клиента всегда направляются на тот же сервер для обработки.

Дополнительные сведения см. в разделе «Кэш в памяти» в ASP.NET Core и Устранение проблем с привязкой сеансов Шлюза приложений Azure.

Распределенный кэш

Используйте распределенный кэш для хранения данных, когда приложение размещается в облачной или серверной ферме. Кэш используется на серверах, обрабатывающих запросы. Клиент может отправить запрос, который обрабатывается любым сервером в группе, если кэшированные данные для клиента доступны. ASP.NET Core работает с распределенными кэшами SQL Server, Redis, Postgres и NCache .

Дополнительные сведения см. в статье Распределенное кэширование в ASP.NET Core.

HybridCache

HybridCache API устраняет разрывы между API IDistributedCache и IMemoryCache. HybridCache — абстрактный класс с реализацией по умолчанию, которая обрабатывает большинство аспектов сохранения в кэше и извлечения из кэша.

Функции HybridCache

HybridCache предоставляет следующие функции, недоступные для других API:

  • Унифицированный API для кэширования как внутри процесса, так и для внепроцессного кэширования.

    HybridCache предназначен для замены существующего использования IDistributedCache и IMemoryCache и предоставляет простой интерфейс API для добавления нового кода кеширования. Если у приложения есть IDistributedCache реализация, HybridCache служба использует ее для дополнительного кэширования. Эта двухуровневая стратегия кэширования позволяет HybridCache обеспечить скорость кэша в памяти и устойчивость распределенного или постоянного кэша.

  • Защита от паники.

    Атака кеша происходит, когда часто используемая запись кеша становится недействительной, и слишком много запросов пытаются одновременно заполнить её заново. HybridCache объединяет параллельные операции, что гарантирует, что все запросы для заданного ответа ожидают первого запроса для заполнения кэша.

  • Настраиваемая сериализация.

    Сериализация настраивается как часть регистрации службы, поддерживается использование специфических для типа и обобщенных сериализаторов через методы WithSerializer и WithSerializerFactory, которые связываются с вызовом AddHybridCache. По умолчанию служба внутренне обрабатывает типы string и byte[], и использует пространство имен System.Text.Json для всего остального. HybridCache можно настроить для других типов сериализаторов, таких как protobuf или XML.

Чтобы увидеть относительную простоту HybridCache API, сравните код, который использует его для кода, который использует IDistributedCache. Вот пример того, как выглядит использование IDistributedCache:

public class SomeService(IDistributedCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync
        (string name, int id, CancellationToken token = default)
    {
        var key = $"someinfo:{name}:{id}"; // Unique key for this combination.
        var bytes = await cache.GetAsync(key, token); // Try to get from cache.
        SomeInformation info;
        if (bytes is null)
        {
            // Cache miss; get the data from the real source.
            info = await SomeExpensiveOperationAsync(name, id, token);

            // Serialize and cache it.
            bytes = SomeSerializer.Serialize(info);
            await cache.SetAsync(key, bytes, token);
        }
        else
        {
            // Cache hit; deserialize it.
            info = SomeSerializer.Deserialize<SomeInformation>(bytes);
        }
        return info;
    }

    // This is the work we're trying to cache.
    private async Task<SomeInformation> SomeExpensiveOperationAsync(string name, int id,
        CancellationToken token = default)
    { /* ... */ }
}

В коде демонстрируется значительный объем работы, чтобы каждый раз все сделать правильно, включая такие аспекты, как сериализация. Кроме того, в сценарии "пропустить кэш" может возникнуть несколько параллельных потоков. Эти потоки могут получать пропущенные кэши, получать все базовые данные, сериализовать их и отправлять данные в кэш.

Ниже приведен эквивалентный код, использующий HybridCache API:

public class SomeService(HybridCache cache)
{
    public async Task<SomeInformation> GetSomeInformationAsync
        (string name, int id, CancellationToken token = default)
    {
        return await cache.GetOrCreateAsync(
            $"someinfo:{name}:{id}", // Unique key for this entry.
            async cancel => await SomeExpensiveOperationAsync(name, id, cancel),
            token: token
        );
    }
}

Код стал проще, и библиотека обеспечивает защиту от лавины запросов и другие функции, которые недоступны в интерфейсе IDistributedCache.

Совместимость

Библиотека HybridCache поддерживает старые среды выполнения .NET, включая .NET Framework 4.7.2 и .NET Standard 2.0.

Дополнительные сведения

Дополнительные сведения см. на следующих ресурсах:

Вспомогательный модуль тегирования для кэша

Кэшируйте содержимое представления MVC или Razor страницы с помощью помощника тега кэша. Вспомогательный элемент для тегов кэша использует кэширование в памяти для хранения данных.

Дополнительные сведения см. в Вспомогательный тег кеша в ASP.NET Core MVC.

Вспомогательная функция тега распределенного кэша

Кэшируйте содержимое из представления MVC или Razor страницы в сценариях распределённого облака или веб-фермы с помощью вспомогательного тега распределённого кеша. Помощник по тегу распределенного кэша использует SQL Server, Redis или NCache для хранения данных.

Для получения дополнительной информации см. Помощник тегов распределенного кэша в ASP.NET Core.

кэширование ответов;

Промежуточное программное обеспечение для кэширования ответов включает кэширование ответов сервера на основе заголовков HTTP Cache-Control.

  • Поведение кэширования реализует стандартную семантику кэширования HTTP.

  • Кэширование основано на заголовках кэша HTTP, аналогичных методу, используемому прокси-серверами.

  • Эта форма кэширования полезна для общедоступных запросов GET или HEAD API от клиентов, в которых выполнены условия кэширования .

  • Для приложений пользовательского интерфейса, таких как Razor Pages, кэширование ответов обычно не является полезным. Браузеры обычно задают заголовки запросов, которые предотвращают кэширование.

    Кэширование вывода (доступно в .NET 7 и более поздних версиях) является лучшим подходом для приложений пользовательского интерфейса. В этом сценарии конфигурация определяет, что кэшировать независимо от заголовков HTTP.

Чтобы проверить кэширование ответов, используйте Fiddler или другое средство, которое может явно задать заголовки запросов. Для тестирования кэширования предпочтительнее явно задать заголовки. Дополнительные сведения см. в разделе "Устранение неполадок промежуточного слоя кэширования ответов>".

Кэширование вывода

Кэширование выходных данных доступно в .NET 7 или более поздней версии.