NTFS-S2K3

экстремальный разгон NTFS\\ скрытые рычаги управления файловой системой

крис касперски ака мыщъх

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

Извечный вопрос, переросший в вооруженный конфликт религиозных войн — бить или не бить? В смысле на разделы. Стучать молотком по винчестеру может только вандал, а таковых среди нас нет, но у всех есть свои аргументы и контраргументы. Но NT это не BSD. И групп цилиндров здесь нет. Что такое группа цилиндров? Чтобы сократить перемещение головок и снизить фрагментацию, файловые системы BSD (и некоторых других UNIX-клонов) бьют раздел на несколько зон, каждая из которых имеет свои служебные структуры данных и в грубом приближении представляет собой полноценный дисковый том за тем исключением, что расположение одного файла в двух (и более) зонах все-таки возможно, чего не скажешь за логические разделы (имея по 100 гектар на дисках С: и D:,200х гектарный файл никак не запишешь…).

Зональное деление приносит огромную пользу, повышая отказоустойчивость диска за счет «размазывания» критической служебной информации по его поверхности, локализуя связанные с ней файлы в одном месте. А теперь возьмем неразбитый диск с NTFS… MFT (служебный файл, хранящий имена, атрибуты и схему размещения всех файлов на диске), находится в начале раздела, индексы (хранящие содержимое каталогов) — где джа велел (например, в конце), ну а сами файлы разбрелись по обширной территории — вот и лови их. (Примечание: компактные файлы, называемые «резидентными» хранятся непосредственно в MFT, что теоретически уменьшает время доступа и подобная техника используется в частности в ReiserFS, однако, как показала практика, вместо ожидаемого увеличения производительности мы имеем тормоза, причем, в NTFS эта фича легальными путями никак не отключаема). В результате, магнитным головкам приходится совершать огромное количество перемещений на большие дистанции, а на большие дистанции головка перемещается совсем не так, как на короткие — сервопривод получает мощный импульс и оказывается… где-то в окрестностях обозначенной зоны, после чего серия коротких перемещений (метод вилки) приводит его к искомому сектору. Это не только усиливает износ механики, но и увеличиваем время поиска информации.

Что делать?! Как достичь предельной скорости?! Очень просто — достаточно разбить диск на несколько разделов, размер которых для дисков с одной физической головой лучше выбирать в пределах 30 гектар. Соответственно, для диска с двумя головками эта цифра составит 60 гектар и т.д. Количество головок можно узнать при помощи различных диагностических программ или скачав datasheet на жесткий диск прямо от производителя. Показаниям BIOS доверять нельзя, поскольку жесткий диск на логическом интерфейсом уровне работает с виртуальными головками, количество которых запросто может достигать 64 штук.

После разбивки, перед форматированием диска, следует определить два важнейших параметра — размер кластера и размер MFT-файла, от правильности выбора которых во многом зависит производительность и судьба всего жесткого диска в целом. Размер кластера выбирается штатным образом в любой утилите форматирования — как консольной, так и графической. Размер кластера всегда кратен размеру сектора (512 байт для всех жестких дисков). Короткие кластеры экономят дисковое пространство (особенно при работе с большим количеством файлов), предотвращая «хвостование» информации на концах. С другой стороны, чем длиннее кластер, тем ниже фрагментация, а, следовательно, жесткий диск может дольше работать без обслуживания (дефрагментации). Имеет смыл выделять разделы диска в зависимости от преобладающего типа файлов (мелкие или крупные), соответственно, назначая и размер кластера.

По умолчанию, при форматировании диска операционная система резервирует под MFT-файл 10% от неформатной емкости тома, высвобождая эту область только при заполнении диска более, чем на 90%. Именно потому считается, что MFT файл не подвержен фрагментации, но тут все не так просто. Если на диске хранится большое кол-во мелких файлов, то размера MFT в какой-то момент не хватает и начинается его рост, подхватывающий фрагментированные куски свободного пространства. Тоже самое происходит и при заполнении диска более, чем на 90% —остаток зарезервированной области усекается, выделясь в общий пул свободного пространства, но обратно в MFT уже не возвращается и потому его фрагментация неизбежна, если, конечно, не позаботится о решении этой проблемы заранее — просто создаем в цикле огромное количество файлов нулевой длинны. Как много? Точное количество зависит от размера структуры FILE_RECORD в MFT (она переменчива), но для наших целей вполне подойдет и упрощенная формула — N_FILEZ == DISK_SIZE/2, где размер тома выражен в килобайтах. Удаляем все файлы кроме пары-тройки, созданных последними. Как нетрудно догадаться ‑ они будут располагаться на самом конце MFT, жестко фиксируя его нижний размер, что предотвратит высвобождение MFT-области в общий пул. Более точная формула отталкивается не от размера тома, а от количество файлов (и каталогов) которые предполагается создавать на данном томе, с учетом того, что при удалении файла, соответствующая ему FILE_RECORD высвобождается не сразу и при создании нового файла из MFT выделяется пространство для новой FILE_RECORD.

Достаточно многие руководства упоминают якобы недокументированный (на самом деле — уже давно как документированный самой Microsoft!) ключ реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem с хитрым параметром NtfsMftZoneReservation, управляющим размером резервируемой MFT-зоны для вновь форматируемых дисков. По умолчанию он равен 1 — резервировать минимум пространства. «Минимум» — это 10%. Однако, поведение системы можно изменить, выбрав значение 2, 3 или даже 4 (максимальный резервируемый объем). Сколько именно Microsoft понимает под «максимумом» она оглашать отказывается и потому о _точных_ значениях ключей 2, 3 и 4 остается только гадать. Мыщъх ковырнул NTFS.SYS драйвер дизассемблером, но резервируемый объем непостоянен и разнится от версии к версии, более того, даже если мы зарезервируем, например, 50% диска — это все равно не решит проблемы фрагментации NTFS, поскольку, по мере заполнения диска зарезервированное пространство автоматически высвобождается, а вот метод, предложенный мыщъхем (создание большого кол-ва мелких файлов с их последующим удалением), работает на ура. Так что возьмем его себе на вооружение.

А вот ключ NtfsMemoryUsage — нереально полезен. По умолчанию выставленный в 1, он ограничивает аппетит NTFS в плане использования памяти, устанавливая жестокие лимиты на размер дискового кэша и количество информации, хранимой для открытых файлов. Для рабочих станций — все ок, но для сервера, оснащенного большим количеством RAM и чувствительного к быстродействию дисковой подсистемы, это значение лучше всего установить в 2, после чего перезагрузиться, чтобы изменения вступили в силу, а пока сервер загружается рекомендуется почитать http://technet2.microsoft.com/windowsserver/en/library/9fcf44c8-68f4-4204-b403-0282273bc7b31033.mspx?mfr=true, чтобы лучше понимать, что же такое мы сейчас сделали.

Рисунок 1 сервер, работающий с большим количеством файлов, нуждается в более демократических квотах на NTFS

Microsoft поставляет две версии своих операционных систем: free build и checked/debug build. Если на коробке ничего не написано, то это с 99% вероятностью — free build, предназначенный для промышленной эксплуатации и встречающийся повсеместно — как на серверах, так и на рабочих станциях.

checked/debug сборки откомпилированы с менее агрессивной оптимизацией и содержат намного более жестокую систему проверок. Там, где free build продолжает работать, отладочная сборка диагностирует потенциально опасную ситуацию, записывая соответствующее сообщение в лог/debug print или даже останавливая машину, чтобы она сама себе не навредила.

Мыщъх уже давно использует отладочную версию NTFS.SYS-драйвера, вытащенную из checked-сборки и получает сообщения о том, что файловая система чувствует себя нехорошо и неплохо бы запустить chkdsk, чтобы проверить целостность всех системных структур. Как следствие — ни одного сбоя за последние ~10 лет. К тому же, отладочная сборка блокирует работу многих нехороших программ, лезущих в NTFS.SYS своими грязными руками, отсекая руткитов и про-активные механизмы некоторых антивирусов, реализованные кое-как и приносящих больше вреда, чем пользы.

Отладочный SP3 для Windows Server 2003 можно бесплатно скачать (перетянув чуть больше 400 метров) http://www.microsoft.com/downloads/details.aspx?FamilyId=096C54B5-7584-4A85-97E6-251A7606809E&displaylang=en или же получит по почте, подписавшись на MSDN. Тут кому как удобнее.

Работать на полностью отладочной версии сервера — не рекомендуется по соображениям производительности (точнее, полного отсутствия таковой), но вот позаимствовать один лишь NTFS.SYS драйвер — можно. Дистрибутив представляет собой обычный CAB, обернутый EXE, и потому продвинутые архиваторы раскрывают его без труда. Как вариант — можно установить отладочную сборку на отдельную машину, с которой и вытащить NTFS.SYS.

Вот, наконец, разбитый на раздели и отформатированный диск лежит перед нами и, тихо жужжа, начинает заполняться файлами. Только… что-то он тормозит, да и красный светодиод мигает даже когда к приводу нет видимых обращений. Зато есть масса невидимых. Для ускорения доступа к данным, Microsoft реализовала систему индексации, задействованную по умолчанию и отключаемую через свойства диска — контекстное меню из проводника  Properties, вкладка «General», а там галочка напротив пункта «Allow Indexing Service to index the disk for fast file searching».

Рисунок 2 отключение службы индексации ускоряет доступ к данным и уменьшает износ жесткого диска

Сбрасываем ее к чертям собачим! Все равно никакого быстрого поиска мы не получим, потому как служба от рождения тупая, а локальные поисковики от независимых производителей (например, от Google) работают через свои собственные механизмы. Так что пользы от индексации все равно никакой. Зато тормоза и повышенный износ дисков.

Вместе с индексацией рекомендуется отключить и журналирование. Как известно, NTFS – журналируемая файловая система, что выдается Microsoft за ее достоинство, хотя это, скорее, недостаток. Журнал не только занимает место, не только отнимает драгоценное время, замедляя интенсивные дисковые операции, но и в некоторых случаях приводит к полному краху — в коде, связанном с поддержкой журнала, за всю историю существования NTFS, было обнаружено по меньшей мере три ошибки, ушедших в релиз и приводящих к BSOD при попытке монтирования NTFS тома, что делало данные практически недоступными. «Практически» потому что знающие люди использовали загрузочные диски с Linux, поддерживающие NTFS на очень базовом уровне (то есть _без_ журналирования), перегоняя все ценные файлы по сети на соседний компьютер или уничтожая журнал в дисковых редакторах/системных утилитах.

Зачем лишний геморрой?! Берем штанную утилиту fsutil.exe, входящую в штатный комплект поставки Windows Server 2003, и удаляем журнал, запрещая журналирование для диска X: следующим образом: «fsutil usn deletejournal /D X:» и все! Если мы потом захотим вернуть журнал на место — нет проблем! «fsutil usn createjournal m=1000 a=100 X:» (значение параметров m и a разъясняется на http://technet2.microsoft.com/windowsserver/en/library/aaa50323-cf1b-4026-b712-33334f99c0e71033.mspx?mfr=true).

Вместе с журналированием, можно отключить и шифрование, обратившись к уже известному нам ключу реестра HTLM\System\CurrentControlSet\Control\FileSystem и создав там параметр NtfsDisableEncryption типа DWORD, установленный в 1. После перезагрузки системы попытка применения атрибута шифрования к файлам и папкам будет выдавать ошибку, что очень хорошо! Почему хорошо? Да потому, что система шифрования в Server 2003 реализована далеко не самым лучшим образом, механизм резервирования ключей неотложен, а без ключей все зашифрованные данные становятся недоступными. Пользователи, не разбирающиеся в администрировании, но уже освоившие мышь, зачастую шифруют все данные к которым только имеют доступ и все работает! Ну чуть-чуть падает скорость, что трудно заметить. Но вот при перестановке сервера после падения или хакерской атаки, «энтузиазм» пользователей выплывает наружу, и хотя данные за разумное время можно расшифровать и без ключа, лучше пресечь проблему на корню.

Рисунок 3 после запрета шифрования, всякая попытка применения данного атрибута приводит к сообщению об ошибке

Параметр NtfsDisableCompression того же самого ключа реестра запрещает применение атрибута сжатия для всех файлов. Чем плохо сжатие? А тем, что сжатые файлы труднее восстанавливать в случае краха диска. Их не поддерживают утилиты автоматизированного восстановления (мне не известно ни одной, которая бы поддерживала), их не понимают драйвера для NTFS от Linux'а, а спецы по восстановлению увеличивают сумму контракта как минимум на порядок. И зачем все это?! К тому же NTFS жмет плохо, сжатые файлы тормозят и жрут память, что для сервера, работающее с большим количеством файлов единовременно, весьма и весьма актуально.

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

Как быть? Что делать? Увы… это фундаментальная проблема NTFS, не имеющая универсальных решений. Если это возможно, следует уменьшить количество файлов в каталоге, разбросав их по подкаталогам, причем именовать файлы желательно так, чтобы на первые буквы имени приходилось максимум различий, т.е. file_1, file_2, file_3… будет тормозить сильнее, чем 1_file, 2_file, 3_file. Вроде бы мелочь, а разница в скорости колоссальна!

Каталоги, содержащие кучу мелких файлов, к которым постоянно происходят обращение лучше всего размещать на виртуальных дисках, не жалея оперативной памяти. Полученное ускорение покроет все расходы с головой. Достаточно замерять сколько времени компилируется какой-нибудь «монстр» на реальном и виртуальном диске (впрочем, Windows-администраторы редко компилируют файлы, так что этот пример идет мимо кассы).

Рисунок 4 дефргаментатор O&O Defrag Professional Edition за работой

Другая проблема NTFS связана с фрагментацией. Несмотря на то, что изначально она разрабатывалась как файловая система практически свободная от фрагментации, стратегия «правильного» выделения дискового пространства навечно осталась в стадии разработки и текущие версии NTFS фрагментируются приблизительно так же, как и FAT, что ведет к неуклонной деградации производительности.

Причем, штатный дефрагментатор, представляющий собой «кастрированный» вариант коммерческого дефрагментатора «O&O Defrag», не умеет дефрагментировать открытые файлы, к которым в первую очередь относятся: файл подкачки, реестр, куча системных файлов и т.д. и т.п. А потому, с каждым днем сервер тормозит все сильнее и сильнее и единственный путь вернуть былую производительность купить полную версию O&O Defrag или любого другого достойного дефрагментатора, поддерживающего дефраментацию в boot-time, то есть на стадии загрузки, когда никакие файлы еще не открыты, а те, что все-таки открыты, приходится обрабатывать с умом, хотя какой тут ум?! boot-программы исполняются в монопольном режиме задолго до наступления многозадачности и потому риска, что кто-то обратиться к дефрагментируемым данным в момент их перемещения здесь нет.

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

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

NTFS поддерживает «разряженные» (sparse) файлы, выделяя дисковое пространство только актуальным данным и подсовывая нули для тех данных, которые еще не были проинициализированы, сокращения тем самым размер файла (иногда в десятки, сотни и даже тысячи раз!). Чтобы назначить файлу атрибут разряженного следует воспользоваться утилитой fsutil из штатного комплекта поставки Server 2003 вызывав ее с ключом «sparse setflag» («fsutil sparse setflag X:\nezumi.txt»), но это еще не все! После того, как файл создан и заполнен данными, из него можно выбить весь «пух», дав команду «fsutil sparse setrange FileName BeginningOffset Length», где BeginningOffset — смещение начала разряженной области (обычно равное нулю), а length – ее длинна (обычно равная размеру файла, округленного до размера кластеров).

Практический пример использования приведен на картинке ниже:

ntfs-s2k3_image_4.jpg

Рисунок 5 внутреннее устройство разряженных файлов

Рисунок 6 разряженный файл nezumi.txt имеет длину 9 Мбайт, занимая на диске всего 2 Кбайта, причем, он не сжат ;-) он _разряжен_