Как я могу превысить 60% предела памяти IIS7 в приложении кэширования ASP.NET

Извините, если это скорее сбой сервера, чем переполнение стека. Вроде на границе.

У нас есть приложение, которое кэширует большой объем данных о продукте для приложения электронной коммерции с использованием кэширования ASP.NET. Это объект словаря с 65 тысячами элементов, и по нашим расчетам размер объекта составляет примерно 10 ГБ.
Проблема:

  1. Объем памяти, который потребляет объект, кажется, намного превышает наши расчеты в 10 ГБ.

  2. САМАЯ БОЛЬШАЯ ПРОБЛЕМА: мы не можем использовать более 60% из 32 ГБ на сервере.

Что мы уже пробовали:

В machine.config/system.web (sf не разрешает теги, простите за форматирование):

processModel autoConfig="true" memoryLimit="80"

В web.config/system.web/caching/cache (sf не разрешает теги, извините за форматирование):

 privateBytesLimit = "20000000000" (and 0, the default of course)
 percentagePhysicalMemoryUsedLimit = "90" 

Окружающая среда: Windows 2008R2 x64, 32 ГБ ОЗУ, IIS7.

Кажется, ничто не позволяет нам превысить значение 60%. Смотрите скриншот таскмана.

http://www.freeimagehosting.net/image.php?7a42144e03.jpg


person evilknot    schedule 11.06.2010    source источник
comment
Обоснованное предположение: сервер перенастраивает свою память, чтобы приспособиться к возросшей рабочей нагрузке, которую вы на него набрасываете, используя больше файла подкачки для компенсации или быстрее собирая память. Что-то такое. Как выглядит вкладка «Производительность» в Taskman при увеличении нагрузки? Увеличивается ли размер файла подкачки?   -  person Robert Harvey    schedule 11.06.2010
comment
@Robert: Swap остается практически неизменным (что имеет смысл, поскольку это кеш в памяти). Хотя стоит проверить. @all: мне интересно, является ли проблемой размер одного объекта. Требует ли GC определенное свободное пространство для перемещения объектов, а этот один объект превышает его?   -  person evilknot    schedule 11.06.2010
comment
Вы меняете местами объекты в словаре и из него? Если да, то это может оказывать давление на сборщик мусора, поскольку каждый обмен освобождает объект, который в какой-то момент должен быть удален. Сборщик мусора может не ждать, пока у вас закончится память, прежде чем он выполнит сбор. Некоторое профилирование памяти может быть в порядке.   -  person Robert Harvey    schedule 11.06.2010
comment
это всегда одна и та же точка использования памяти, которая терпит неудачу? что-нибудь в журнале событий во время смерти? еще одна случайная догадка — фрагментация памяти. Если у вас есть отладчик, подключенный до того, как он умрет, будет ли что-нибудь выброшено, когда он умрет? (ООМ, например)   -  person James Manning    schedule 11.06.2010
comment
@Robert Harvey: мы просто заполняем кеш один раз, когда приложение запускается.   -  person evilknot    schedule 11.06.2010
comment
@James: Да, это определенно выдает ошибку нехватки памяти вместе с YSOD.   -  person evilknot    schedule 11.06.2010
comment
звучит как фрагментация памяти ИМХО - я бы посмотрел на кэширование по-другому, если это возможно, или проще, добавив больше памяти? :)   -  person James Manning    schedule 12.06.2010


Ответы (2)


Немного поздно, но у меня почти такая же проблема. Проблема с настройкой memoryLimit в processModel заключается в том, что она, кажется, не имеет никакого эффекта, несмотря на то, что она задокументирована как таковая.

percentagePhysicalMemoryUsedLimit похоже, что он должен что-то делать, но не имеет никакого эффекта.

privateBytesLimit="20000000000" действительно работает. Я пошел и отладил процесс и нашел объект CacheMemorySizePressure, и он успешно получил значение и установил его в _memoryLimit. Я бы дважды проверил это.

Другой вариант — установить порог перезапуска использования частной памяти в пуле приложений IIS. Это также должно быть подхвачено и переопределить ограничение по умолчанию в 60%.

Третий вариант — использовать новый класс MemoryCache. и установить на нем PhysicalMemoryLimit.

person RandomEngy    schedule 14.02.2012

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

Мы потратили много времени, работая над этим, и сдались. На самом деле мы используем более тонкие объекты для хранения в кеше и получаем более полные объекты по мере необходимости.

Когда нам нужно было это обдумать, мы исследовали Memcached и Velocity, но пока отказались от их развертывания. Однако они более функциональны.

Также как вы храните элементы в кеше с помощью кода? Вы кладете их туда при запуске приложения или после первого запроса для каждого? Причина, по которой я спрашиваю, заключается в том, эффективны ли ваши ключи кеша и на самом деле вы снова и снова заполняете кеш и ничего не извлекаете (это может быть случай только одного типа объекта). Нам удалось сделать это один раз, например, добавив время к ключу кэша для конкретной даты.

person ArtificialGold    schedule 11.06.2010
comment
Мы определенно изучаем другие тайники. Мы просто заполняем кеш один раз, когда приложение запускается, и это не меняется. Мы рассматривали вышеперечисленное, помимо nCache. Спасибо! - person evilknot; 11.06.2010
comment
+1, кеш asp.net здесь действительно неправильный - вы, вероятно, хотите что-то еще и вне процесса. - person Wyatt Barnett; 14.02.2012