Использование нескольких экземпляров MemoryCache

Я хотел бы добавить возможности кэширования в мое приложение, используя System.Runtime.Caching пространство имен, и, вероятно, хотите использовать кэширование в нескольких местах и в разных контекстах. Для этого я хочу использовать несколько экземпляров многорычажка.

Я вижу здесь что использование более одного экземпляра MemoryCache не рекомендуется:

MemoryCache не является одноэлементным, но вы должны создать только несколько или потенциально только один экземпляр MemoryCache и код, который кэширует элементы, должен использовать эти экземпляры.

как несколько экземпляров MemoryCache повлияют на мое приложение? Я нахожу это странным, потому что мне кажется, что использование нескольких кэшей в приложении-довольно распространенный сценарий.

EDIT: более конкретно, у меня есть класс, который должен сохранить кэш для каждого экземпляра. Должен ли я избегать использования MemoryCache и искать другое решение для кэширования? С помощью MemoryCache в этой ситуации считается плохим, и если да, то почему?

2 ответов


недавно я сам прошел через это. Учитывая, что кэш в памяти будет специфичным для процесса (не общим для нескольких экземпляров веб-сайта или собственного бизнес-приложения или нескольких серверов), нет никакой пользы от наличия нескольких MemoryCache экземпляры, за исключением организационных причин кода (которые могут быть достигнуты другими способами).

кэш памяти предназначен для использования в одиночку в основном из-за его возможностей управления памятью. В дополнение к представлению счетчики (которые имеют некоторые накладные расходы) MemoryCache также может истекать элементы, когда он работает из выделенной памяти.

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

С MemoryCache.CacheMemoryLimit Собственность

используя только один экземпляр MemoryCache, он может эффективно применять это управление памятью во всем экземпляре приложения. Истечение срока действия наименее важных элементов во всем приложении. Это обеспечивает максимальное использование памяти, не превышая ваши аппаратные возможности. Ограничивая область действия любого MemoryCache (например, одного экземпляра класса), он больше не может эффективно управлять памятью для вашего приложения (поскольку он не может "видеть" все). Если все эти Кеши были "заняты", вам может быть сложнее управлять памятью, и она никогда не будет почти такой же эффективной.

Это особенно чувствительно в приложениях, которые не имеют выделенного сервера. Представьте, что вы запускаете свое приложение на общем сервере, где вам выделено только 150 МБ ОЗУ (общий дешевый хостинг $10/month), вам нужно рассчитывать на свой кэш, чтобы использовать его по максимуму, не превышая его. Если вы превысите это использование памяти, ваш пул приложений будет переработан и ваше приложение теряет все в кэшах памяти! (обычная дешевая практика хостинга) то же самое может применяться к не-веб-приложению, размещенному в доме на некотором общем корпоративном сервере. То же самое, вам говорят не забивать всю память на этой машине и мирно сосуществовать с некоторыми другими бизнес-приложениями.

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

Я знаю, что MemoryCache-это не веб-версия системы.Сеть.Кэширование.Реализация кэша, но это иллюстрирует логику реализации кэша. Та же логика может применяться в не-веб-проекте, если у вас нет исключительного использования оборудования. Помните, если ваши силы кэша машина, чтобы начать делать подкачки файлов подкачки, то ваш кэш больше не быстрее, чем кэширование на диске. Вы всегда будете хотеть предел где-то, даже если этот предел 2gb или что-то еще.

в моем случае после прочтения об этом я переключился на использование одного "общедоступного статического MemoryCache" в моем приложении, и я просто разделил кэшированные элементы по их ключам кэша. Например, если вы хотите кэшировать на каждом экземпляре, у вас может быть ключ кэша, например "instance - {instanceId} - resourceName - {resourceId}". Считай это имя интервал записи кэша.

надеюсь, что это поможет!


Я тоже использую несколько. Обычно по одному на тип.

смотреть на!--0--> Я вижу, что он подключается к AppDomain событий и поддерживает счетчики производительности. Я подозреваю, что есть некоторые накладные ресурсы, используя более одного (например, CPU, счетчики и память), и поэтому это не рекомендуется.