Скрытые рычаги управления файловой системой семейства ОС Windows NT
Крис Касперски
NTFS – возможно, самая сложная файловая система из всех, когда-либо разработанных человечеством за всю историю существования компьютерной индустрии. Ее разработчики, в стремлении объять необъятное, скрестили передовые технологии в области баз данных, поиска, сжатия и шифрования информации, вот только забыли прикрутить рычаги управления…
Содержание:
- Полет с жестким диском на пепелаце
- Гравицаппа для NTFS
- Секреты эффективного использования NTFS
- Врезка: Разряженные файлы на службе прогресса
- Боковые выносы
Полет с жестким диском на пепелаце
Извечный вопрос, переросший в вооруженный конфликт религиозных войн, — бить или не бить? В смысле на разделы. Стучать молотком по винчестеру может только вандал, а таковых среди нас нет, но у всех есть свои аргументы и контраргументы. WinNT – это не xBSD, и групп цилиндров здесь нет. Что такое группа цилиндров? Чтобы сократить перемещение головок и снизить фрагментацию, файловые системы xBSD (и некоторых других UNIX-клонов) бьют раздел на несколько зон, каждая из которых имеет свои служебные структуры данных и в грубом приближении представляет собой полноценный дисковый том за тем исключением того, что расположение одного файла в двух (и более) зонах все-таки возможно, чего не скажешь о логических разделах (имея по 100 Гб на дисках С: и D:, двухсот гектарный файл никак не запишешь…).
Зональное деление приносит огромную пользу, повышая отказоустойчивость диска за счет «размазывания» критической служебной информации по его поверхности, локализуя связанные с ней файлы в одном месте. А теперь возьмем неразбитый диск с NTFS… MFT (служебный файл, хранящий имена, атрибуты и схему размещения всех файлов на диске) находится в начале раздела, индексы, ответственные за содержимое каталогов, - в конце, ну а сами файлы разбрелись по обширной территории — вот и лови их (примечание: компактные файлы, называемые «резидентными», хранятся непосредственно в MFT, что теоретически уменьшает время доступа, и подобная техника используется, в частности, в ReiserFS, однако, как показала практика, вместо ожидаемого увеличения производительности мы имеем тормоза, причем в NTFS эта фича легальными путями никак не отключаема). В результате магнитным головкам приходится совершать огромное количество перемещений на большие дистанции, а на большие дистанции головка перемещается совсем не так, как на короткие — сервопривод получает мощный импульс и оказывается… где-то в окрестностях обозначенной зоны, после чего серия коротких перемещений (метод вилки) приводит его к искомому сектору. Это не только усиливает износ механики, но и увеличивает время поиска информации.
Что делать?! Как достичь предельной скорости?! Очень просто — достаточно разбить диск на несколько разделов, размер которых для дисков с одной физической головой лучше выбирать в пределах 30 Гб. Соответственно, для диска с двумя головками эта цифра составит 60 Гб и т.д. Количество головок можно узнать при помощи различных диагностических программ, или скачав hdd datasheet от фирмы-производителя. Показаниям BIOS доверять нельзя, поскольку жесткий диск на логическом интерфейсном уровне работает с виртуальными головками, количество которых запросто может достигать 64 штук.
После разбивки, перед форматированием диска, следует определить два важнейших параметра — размер кластера и размер MFT-файла, от правильности выбора которых во многом зависит производительность и срок службы жесткого диска в целом. Размер кластера выбирается штатным образом в любой утилите форматирования — как консольной, так и графической. Размер кластера всегда кратен размеру сектора (512 байт для всех жестких дисков) и по умолчанию составляет 4 Кб (т.е. 8 секторов). Короткие кластеры экономят дисковое пространство (особенно при работе с большим количеством файлов), предотвращая «хвостование» информации на концах. С другой стороны, чем длиннее кластер, тем ниже фрагментация, а, следовательно, жесткий диск может дольше работать без обслуживания (дефрагментации). Но здесь нужно помнить, что при большем размере кластера отключается встроенная в файловую систему возможность сжатия индивидуальных файлов, а также перестает работать стандартный API дефрагментации.
По умолчанию при форматировании диска операционная система резервирует под 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_MACHINESystemCurrentControlSetControlFileSystem с хитрым параметром NtfsMftZoneReservation, который управляет размером резервируемой MFT-зоны для вновь форматируемых дисков. По умолчанию он равен 1 — резервировать минимум пространства. «Минимум» — это 10%. Однако поведение системы можно изменить, выбрав значение 2, 3 или даже 4 (максимальный резервируемый объем). Сколько именно Microsoft понимает под «максимумом», она оглашать отказывается, и потому о точных значениях ключей 2, 3 и 4 остается только гадать. Я ковырнул драйвер NTFS.SYS дизассемблером, но резервируемый объем непостоянен и разнится от версии к версии, более того, даже если мы зарезервируем, например, 50% диска — это все равно не решит проблемы фрагментации NTFS, поскольку по мере заполнения диска зарезервированное пространство автоматически высвобождается, а вот метод создания большого количества мелких файлов, с их последующим удалением, работает «на ура». Так что возьмем его себе на вооружение.
Что касается ключа NtfsMemoryUsage, то он нереально полезен. По умолчанию выставленный в 1, NtfsMemoryUsage ограничивает аппетит NTFS в плане использования памяти, устанавливая жесткие лимиты на размер дискового кэша и количество информации, хранимой для открытых файлов. Для рабочих станций — здесь все ок, но для сервера, оснащенного большим количеством RAM и чувствительного к быстродействию дисковой подсистемы, это значение лучше всего установить в 2, после чего перезагрузиться, чтобы изменения вступили в силу.
Вот, наконец, разбитый на разделы и отформатированный диск лежит перед нами и, тихо жужжа, начинает заполняться файлами. Только… что-то он тормозит, да и красный светодиод мигает, даже когда к приводу нет видимых обращений. Зато есть масса невидимых. Для ускорения доступа к данным Microsoft реализовала систему индексации, задействованную по умолчанию и отключаемую через свойства диска. Вызываем из проводника контекстное меню, далее Properties, вкладка «General», а там галочка напротив пункта «Allow Indexing Service to index the disk for fast file searching». Сбрасываем ее немедленно! Все равно никакого быстрого поиска мы не получим, зато приобретем тормоза и повышенный износ дисков.
Вместе с индексацией рекомендуется отключить и журналирование. Как известно, NTFS – журналируемая файловая система, что выдается Microsoft за ее достоинство, хотя это скорее недостаток. Журнал не только занимает место и отнимает драгоценное время, замедляя интенсивные дисковые операции, но и в некоторых случаях приводит к полному краху — в коде, связанном с поддержкой журнала, за всю историю существования NTFS в релизных версиях WinNT/200x было обнаружено, по меньшей мере, три ошибки, приводящих к BSOD при попытке монтирования NTFS тома, что делало данные практически недоступными. «Практически» – потому что знающие люди использовали загрузочные диски с Linux, поддерживающие NTFS на базовом уровне (то есть без журналирования), перегоняя все ценные файлы по сети на соседний компьютер или уничтожая журнал в дисковых редакторах/системных утилитах.
Зачем лишние мучения?! Берем утилиту fsutil.exe, входящую в штатный комплект поставки Win2k3, и удаляем журнал, запрещая журналирование для диска X: следующим образом: «fsutil usn deletejournal /D X:», и все! Если мы потом захотим вернуть журнал на место, нет проблем: «fsutil usn createjournal m=1000 a=100 X:».
Вместе с журналированием можно отключить и шифрование, обратившись к уже известному нам ключу реестра HTLMSystemCurrentControlSetControlFileSystem и создав там параметр NtfsDisableEncryption типа DWORD, установленный в 1. После перезагрузки системы попытка применения атрибута шифрования к файлам и папкам будет выдавать ошибку, что очень хорошо! Почему хорошо? Потому что система шифрования в Win2k3 реализована далеко не самым лучшим образом, механизм резервирования ключей неотложен, а без ключей все зашифрованные данные становятся недоступными. Пользователи, не разбирающиеся в администрировании, но уже освоившие мышь, зачастую шифруют все данные, к которым только имеют доступ! Но вот при перестановке сервера после падения или хакерской атаки «энтузиазм» пользователей выплывает наружу, и хотя данные за разумное время можно расшифровать и без ключа, лучше пресечь проблему на корню. Кроме того, шифрование негативно сказывается на быстродействии NTFS.
Параметр NtfsDisableCompression того же самого ключа реестра запрещает применение атрибута сжатия для всех файлов. Чем плохо сжатие? А тем, что сжатые файлы труднее восстанавливать в случае краха диска. Их не поддерживают утилиты автоматизированного восстановления (мне не известно ни одной, которая бы поддерживала), их не понимают драйвера для NTFS от Linux, а спецы по восстановлению в этом случае увеличивают сумму контракта как минимум на порядок. И зачем все это?! К тому же NTFS жмет плохо, сжатые файлы тормозят и жрут память, что для сервера, работающего с большим количеством файлов единовременно, весьма и весьма актуально.
Секреты эффективного использования NTFS
В отличие от FAT32, где все свалено в кучу, NTFS использует двоичную организацию файловых каталогов, что (теоретически) должно увеличить производительность, сократив время поиска файла в каталоге, однако неудачная реализация погубила эту идею, продемонстрировав прямо противоположный эффект. NTFS крайне плохо справляется с каталогами, содержащими десятки и сотни тысяч файлов, особенно если кроме операций открытия (фактически, сводящихся к поиску заданного имени в дереве), мы так же занимаемся созданием новых файлов/удалением старых, вынуждая NTFS перестраивать кучу служебных структур, живописно разбросанных по диску.
Как быть? Что делать? Увы… это фундаментальная проблема NTFS, не имеющая универсальных решений. Если это возможно, следует уменьшить количество файлов в каталоге, разбросав их по подкаталогам, причем именовать файлы желательно так, чтобы на первые буквы имени приходилось максимум различий, т.е. file_1, file_2, file_3… будет тормозить сильнее, чем 1_file, 2_file, 3_file. Вроде бы мелочь, а разница в скорости колоссальна!
Каталоги, содержащие кучу мелких файлов, к которым постоянно происходит обращение, лучше всего размещать на виртуальных дисках, не жалея оперативной памяти. Полученное ускорение покроет все расходы с головой.
Другая проблема NTFS связана с фрагментацией. Несмотря на то, что изначально она разрабатывалась как файловая система, практически свободная от фрагментации, стратегия «правильного» выделения дискового пространства навечно осталась в стадии разработки, и текущие версии NTFS фрагментируются приблизительно так же, как и FAT, что ведет к неуклонной деградации производительности.
Причем штатный дефрагментатор, представляющий собой сильно урезанный вариант коммерческого «O&O Defrag», не умеет дефрагментировать открытые файлы, к которым, в первую очередь, относятся: файл подкачки, реестр, куча системных файлов и т.д. А потому с каждым днем сервер тормозит все сильнее и сильнее, и единственный путь вернуть былую производительность – обзавестись полной версией O&O Defrag или любого другого достойного дефрагментатора, поддерживающего дефрагментацию в boot-time, то есть на стадии загрузки, когда никакие файлы еще не открыты, а те, что все-таки открыты, приходится обрабатывать с умом, хотя какой тут ум?! Boot-программы исполняются в монопольном режиме задолго до наступления многозадачности, и потому риск, что кто-то обратится к дефрагментируемым данным в момент их перемещения, здесь полностью исключен.
Врезка: Разряженные файлы на службе прогресса
NTFS поддерживает «разряженные» (sparse) файлы, выделяя дисковое пространство только актуальным данным и подсовывая нули для тех данных, которые еще не были проинициализированы, сокращая тем самым размер файла (иногда в десятки, сотни и даже тысячи раз!). Чтобы назначить файлу атрибут разряженного, следует воспользоваться утилитой fsutil из штатного комплекта поставки Win2k3, вызвав ее с ключом «sparse setflag»: «fsutil sparse setflag X:nezumi.txt», но это еще не все! После того, как файл создан и заполнен данными, из него можно выбить весь «пух», дав команду «fsutil sparse setrange FileName BeginningOffset Length», где BeginningOffset — начальное смещение разряженной области (обычно равное нулю), а Length – ее длина (обычно равная размеру файла, округленного до размера кластеров).
INFO
- Старайся не располагать файл подкачки на зеркальном RAID массиве – это снизит скорость работы.
WWW
- На technet2.microsoft.com можно найти интересные статьи, посвященные работе с NTFS.
WARNING
- Поскольку версий NTFS существует намного больше одной, то при использовании дисковых утилит от сторонних разработчиков требуется проверить их на совместимость с нашей версией, путем установки ее (со всеми обновлениями) на виртуальную машину/отдельный жесткий диск, но даже если тест прошел «на ура», настоятельно рекомендуется освежить резервные копии, особенно если дисковая утилита на живой машине запускается в первый раз, и никто не знает, как она себя поведет.
Статья опубликована в августовском номере журнала «Xakep» за 2008 год.



