На одном из файловых серверов под управлением Windows Server 2008 R2 обнаружилась проблема с высокой загрузки оперативной памяти (RAM), выливающаяся в проблемы с производительностью сервера и запущенных на нем служб. Как оказалось, память забивалась системным файловым кэшем с метаданными файловой системы. Проблеме потенциально подвержены все файловые сервера с большим количеством файлов, к которым обращаются пользователя. Наиболее критична проблема для 64 битных версий Windows, на которых размер метафайла в памяти может занять практически всю емкость установленной оперативной памяти. В статье разберемся как проявляется проблема, выявим ее источники и способы решения.
Высокая загрузка оперативной памяти на файловом сервере Windows
Проблема проявляется следующим образом: в диспетчере задач (Task Manager) видим, что на сервере оперативная память занята на 95-99%.
Перейдя на вкладку процессов, не удастся найти какой-то утекший процесс с аномально высоким потреблением памяти. Кроме того, если навскидку сложить память, занятую всеми процессами, отображаемыми в диспетчере задач, даже близко не удается приблизиться к 50% физической памяти, установленной на сервере. Так кто же съел всю память?
Реальный расклад по использованию оперативной памяти может дать утилита RAMMap (Марка Руссиновича). Качаем архив с утилитой и запускаем из архива файл RAMMap.exe с правами администратора. На вкладке Use Counts, видим, что больше всего физической памяти использует объектом Metafile (в нашем случае на него приходится 11 из 25 Гб оперативной памяти сервера).
Что такое метафайл в Windows?
Метафайл (Metafile) — это часть системного кэша, который содержит метаданные файловой системы NTFS и используется для увеличения быстродействия файловой системы при доступе к файлам. Метаданные NTFS включают в себя данные таблицы MFT (Master File Table). Для каждого файла/папки, к которому обращались пользователи, в метафайле создается соответствующий блок, размером как минимум 1 Кб (запись об атрибуте каждого файла занимает 1кб, и каждый файл имеет как минимум один атрибут). Таким образом, на файловых серверах с большим количеством файлов, к которым идут постоянные обращения, размер системного кэша NTFS (метафайла) может достигать нескольких гигабайт.
Отключить этот кэш или управлять им с помощью стандартных средств Windows не получится. Как решение, можно увеличить количество памяти на сервере, но реализуемо это далеко не всегда.
Если перезагрузить сервер, память используемая метафайлом освобождается, но со временем размер метафайла в памяти все равно начинает неконтролируемо расти.
К примеру, оценить размер MFT таблицы можно с помощью еще одной утилиты Руссиновича – ntfsinfo. К примеру, в нашем примере для 2 Тб диска размер MFT таблицы составляет 13 Гб.
Быстрая очистка метафайла MFT в памяти
Утилита RAMMap предоставляет возможность быстрой очистки используемой памяти от мусора без необходимости перезагрузки сервера. Для этого нужно в меню выбрать раздел Empty -> Empty System Working Set. После этой операции размер памяти под metafile уменьшился в десятки раз, а процент использования RAM сервером упал с 95% до 26%.
Основной недостаток такого метода – процесс очистки ручной и никак не автоматизируется.
Служба Dynamic Cache Service для управления файловым кэшем
Другим, более кардинальным, решением проблемы высокой загрузки оперативной памяти метафайлом файловой системы является установка службы Dynamic Cache Service (http://www.microsoft.com/en-us/download/details.aspx?id=9258). Данная служба через системные API позволяет управлять параметрами выделяемого кэша.
Установка DynCache довольно простая (подробные инструкции есть в архиве с программой).
- Копируем файл в DynCache.exe в каталог %SystemRoot%\System32
- Создадим службу DynCache командой
sc create DynCache binpath= %SystemRoot%\System32\DynCache.exe start= auto type= own DisplayName= "Dynamic Cache Service"
- Импортируем файл DynCache.reg в реестр (содержит дефолтные значения)
- Изменим значения следующих ключей реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DynCache\Parameters
- MaxSystemCacheMBytes: 4096 (dec) – максимальный размер кэша
- MinSystemCacheMBytes: 100 (dec) – минимальный размер
Примечание. Эти и другие параметры службы DynCache нужно отрегулировать в соответствии с количеством установленной памяти и нагрузкой на сервер, требуемой производительности и т.д. Как правило, не стоит задавать размер кэша больше, чем половина установленной на сервере RAM. После внесения изменения службу DynCache перезапускать не нужно, т.к. изменения отслеживаются динамически. - Запустим службу командой
sc start DynCache
В нашем случае, после установки службы DynCache, использование памяти метафайлом перестало превышать заданного нами значения 4 Гб. Пользователи каких-либо проблем с ухудшением производительности файлового сервера не выявили.
Поделюсь результатами на терминальном сервере.
До http://imgur.com/kEYgOKi
После http://imgur.com/RaacJdf
Большое освобождение памяти происходит за счёт Mapped File.
Mapped File, — это закешированные в памяти файлы, дающие увеличения I/O приложениям. Как правило, они автоматически вычищаются из памяти, не вызывая проблем с перерасходом RAM. Metafile более капризен в этом плане, и не отдает без боя захваченную память. Это вызывает проблемы на файловых и нагруженных веб серверах (под Windows)
Думаю в вашем случае через пару тройку часов размер кэша Mapped File опять вернется к начальным значениям.
Не стартует служба, ошибка 216: 0xd8
((
Вы используете неправильную версию.
Возьмите из другой папки.
Память занята под 90%, самый толстый Nonpaged pool). Куда смотреть?
Можно определить драйвер, который утек в невыгружаемом пуле через poolmon. См. статью https://winitpro.ru/index.php/2017/12/06/high-non-paged-pool-windows/
В сторону драйверов.
Есть ли такой же функционал на windows server 2016?
Здраствуйте. Нужна помощ. При установке Win server 2008 установщик не может найти диски. Требуя установить какие та драйвера дисков. Есть предположение что windows не видит sata дисков. Но я никак не могу найти эти драйвера. Подскажите в каую сторону надо копать?
Ищите драйвера для вашего контроллера жестких дисков. Их можно добавить непосредственно в дистрибутив Windows Server (см. пример), или загрузить на этапе установки с флешки например (при установке будет кнопка Load driver) https://winitpro.ru/index.php/2016/12/21/integraciya-drajvera-kontrolera-usb-3-0-v-distributiv-windows-7/
День добрый.
Пробовал воспользоваться вашим способом.
Все получилось, все отлично, служба заработала.
Вот только реакции от нее никакой нет — кэш как заполнял память, так и заполняет.
Метафайл как расширялся, так и расширяется, плюя на указания в реестре.
Подскажите?
У вас Windows Server 2008 R2 и используется именно под файловые сервер?
Да, именно.
Вопрос с метафайлом отпал, но Mapped file жрет очень много.
Вот я тоже бьюсь с поиском того как можно ограничить этот MappedFile…
Пока только вручную обнулять через RamMap … хоть бы ключ был бы из командной строки его сбрасывать — в планировщик воткнул и все…. нет же… ((((
Автоматизация через AutoIT
Скрипт:
;—————————————————————————-
#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Res_Language=1049
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;—————————————————————————-
; SAM — 20/11/2013
;—————————————————————————-
; RunRamMap — оболочка для запуска утилиты Sysinternals RamMap
; — после запуска программы выполняется очистка Standby памяти
; — после 10-15 секунд работы программа закрывается…
;
; Оригинальная утилита должна находиться в каталоге: C:\UTIL\RAMMap\RAMMap.exe
;—————————————————————————-
; RamMap — работает только для Windows Vista и выше …
;—————————————————————————-
Local $hWnd ; идентификатор окна программы
Local $ret ; идентификатор программы
; Если программа еще не запущена — запускаем RamMAP
If Not WinExists(«[CLASS:RamMapClass]») Then
$ret = ShellExecute(‘C:\UTIL\RAMMap\RAMMap.exe’)
If @error Then
MsgBox(4096, ‘Сообщение’, ‘Ошибка запуска RamMap.exe.’, 30)
Exit 1
EndIf
EndIf
; Ожидаем появление окна программы RamMap
$hWnd = WinWait(«[CLASS:RamMapClass]», «», 10)
If Not $hWnd Then
MsgBox(4096, ‘Сообщение’, ‘Окно RamMap не найдено, завершаем работу’)
Exit 2
Else
WinActivate(«[CLASS:RamMapClass]», «») ; наше окно — активное
EndIf
; Выбираем пункт «Empty Standby List» в меню «Empty» программы
WinMenuSelectItem($hWnd, », ‘&Empty’, ‘Empty S&tandby List’)
; ждем выполнение очистки 5 сек… (ориентировочно…)
Sleep(5000)
; обновляем экран
Send(«{F5}»)
; Ждем 5 секунд, чтобы увидеть результат и выйти…
Sleep(5000)
WinMenuSelectItem($hWnd, », ‘&Empty’, ‘Empty S&ystem Working Set’)
; ждем выполнение очистки 5 сек… (ориентировочно…)
Sleep(5000)
; обновляем экран
Send(«{F5}»)
; Ждем 5 секунд, чтобы увидеть результат и выйти…
Sleep(5000)
; Закрываем программу.
WinClose($hWnd)
;—————————————————————————-
Отлично! Почему бы и нет 🙂