Mfs файловая система в RAM
Файловая система MFS представляет собой частный случай более широкого явления – механизма memory disks, через который осуществляется также поддержка виртуальных дисков в оперативной памяти (аналог RAM-дисков в DOS и Linux) и доступ к файлам (например, iso-образам CD-дисков) как к реальным устройствам (аналог loopback-устройств в Linux). Однако в этой заметке мы ограничимся только рассмотрением собственно mfs – о RAM-дисках я смогу рассказать, когда у меня дойдут до них руки, а обращение с файлами как с устройствами будет рассмотрено при описании процесса записи CD-R/RW.
Назначение mfs – заменить собой дисковые устройства там, где требуется быстрая, но не обязательно долговременная, запись. То есть – для всякого рода промежуточных каталогов при архивации/разархивации, пакетной конвертации графических файлов, а также компиляции программ.
Наиболее целесообразно использовать mfs для монтирования в каталог типа /tmp, предназначенный для хранения всякого рода временных файлов, а также периодически задействовать ее под каталог /usr/obj, куда помещаются промежуточные продукты компиляции при полном rebuilding’е системы – исполнение команды make world, и (по новой схеме этого процесса) при пересборке ядра.
Ну, про целесообразность размещения временных файлов в оперативной памяти – думаю, ясно без комментариев. А вот про /usr/obj – скажу чуть подробнее.
При компиляции программ образуется изрядное количество объектных модулей, которые нужны только в процессе сборки. После образования исполнимых файлов и их инсталляции они оказываются не просто ненужными, а иногда даже вредными (если потребуется пересборка программы из того же дерева исходников, но с другими параметрами). Поэтому возникает естественное желание отделить объектные файлы от первозданного древа исходников, выделив под них отдельную ветвь файловой системы.
С другой стороны, при сборке таких сложных программных комплексов, как базовая система FreeBSD или ее ядро, создается очень большое количество объектных файлов. Обычно они не велики по размеру, но ведь каждый из них требует себе операции записи/чтения. Что, не смотря на все усовершенствования Soft Updates, остается не самой сильной стороной файловой системы UFS. Так что перенесение их с диска в оперативную память должно дать некоторый выигрыш во времени при операциях make world или пересборке ядра.
Правда, оценки такого прироста, встречающиеся в литературе, весьма изменчивы – от первых процентов до 10-15%. Собственно говоря, выигрыш от компиляции в mfs очень зависит от того, что именно компилируется: большое количество мелких пакетов может собираться просто <<с песнями>>, для сборки же тяжеловесов вроде ядра или оконной системы X прирост скорости может оказаться весьма скромным.
По моим измерениям, операция make world без монтирования mfs в /usr/obj выполняется (на P-4/2,53 с 1 Гбайт памяти) в среднем за 23 минуты, с использованием mfs в качестве временного хранилища (512 Мбайт) – за 21 минуту. То есть выигрыш от использования mfs составляет менее 10%. Много это или мало – каждый может решить для себя, но ведь, что характерно – абсолютно задарма.
Однако монтирование mfs в /usr/obj имеет еще и побочный полезный эффект – отпадает необходимость в выполнении операций типа make clean для очистки дерева исходников от промежуточных продуктов компиляции: перестройка <<мира>> и ядра при этом каждый раз будет выполняться с <<чистого листа>>. Тоже вроде пустяк, но ведь невредно, и усилий не требует ни малейших…
Во всяком случае, повредить производительности (при достаточном количестве оперативной памяти, конечно, – но ведь нынче и 512 ее мегабайт вовсе не редкость) mfs ни в коем случае не может. В принципе, размер файловой системы mfs можно определить и в размере большем, чем наличествующей физически памяти. Ведь во FreeBSD физическое ОЗУ и область подкачки на диске составляют единое адресное пространство – виртуальную память. И по исчерпании первой под mfs будет задействоваться раздел подкачки.
Казалось бы, это полностью обесценивает все преимущества mfs. Однако – не совсем. Потому что во FreeBSD работа виртуальной памяти организована весьма эффективно. То есть сброс данных из ОЗУ на диск происходит не при исчерпании памяти, – своппингу подвергаются страницы, к которым долго не происходит обращений. И в результате непосредственно в ОЗУ, то есть области максимально быстрого доступа, практически всегда находятся наиболее, так сказать, актуальные фрагменты загруженных данных. А потому mfs способна дать некоторый выигрыш даже при частичном переносе ее в раздел подкачки. Хотя, конечно, наиболее резонно применять mfs при большом объеме физической памяти – исходя из общих соображений, от 512 Мбайт и выше.
В общем, думаю, что mfs почти в любом случае – штука как минимум не вредная. Так что остается лишь ее задействовать. Для чего требуется поддержка ядром дисков в памяти (md – memory disks) без дальнейшей детализации, что уже имеется в GENERIC по умолчанию. А потом – только сконфигурировать mfs соответствующей командой:
В результате в каталоге /dev будет создан файл устройства – md#, где:#
– порядковый номер виртуального диска, если ранее таковых не было - нулевой.
Можно указать и вполне конкретный номер, например, md1. Файловая система на нем образуется автоматически, без всяких там newfs и монтируется в указанный каталог.
Создаваемая таким образом mfs будет безразмерной, то есть в перспективе может занять всю виртуальную (RAM+swap) память. Если это почему-либо нежелательно, размер mfs можно ограничить опцией -s – задав ее значение в блоках (просто число), килобайтах (##k) или мегабайтах (##m).
Можно указать и некоторые другие опции монтирования, как для обычных disk-based файловых систем. Так, опция -S позволяет отказаться для mfs от механизма Soft Updates (очевидно, что его действенность в условиях обмена память-память сомнительна). А вот с помощью -o async можно задействовать для mfs-ветви полностью асинхронный режим работы. Который для нее никаких отрицательных последствий иметь не может – все равно ее содержание пропадет при перезагрузке, вне зависимости – аварийной ли, корректной (правда, и в сколь-нибудь существенном выигрыше от него я также не уверен). Ну и, конечно, никакой необходимости в обновлении атрибута atime mfs не испытывает, и потому добавить к -o еще и atime – просто сам бог велел.
Остается решить, сколько памяти отдать на растерзание mfs в каталогах /tmp и /usr/obj. Объем под файловую систему /tmp во многом зависит от сферы применения машины (десктоп ли это, или сервер). По умолчанию, скажем, в sysinstall для нее предлагается отвести 256 Мбайт – немного в масштабах современных дисков, но отрезать от оперативной памяти – жалко. Тем более что в типичном десктопе из них будут обычно заняты какие-то сотни килобайт (в основном под временные файлы оконной системы X и чего-нибудь вроде KDE). Так что я, например, при 512 Мбайт RAM кинул под mfs в /tmp 32 Мбайт -
и недостатка пока не испытал ни разу (повторяю, для сервера расчеты могут быть совершенно другими). Убедившись, что так оно и есть, можно предписать монтирование mfs в каталог /tmp автоматически, для чего вписать в /etc/fstab строку:
А вот под /usr/obj потребуется немало места. С целью выполнения операций make world и make buildkernel я отвел под нее 512 Мбайт (из 1024). И по окончании обеих процедур объем mfs был исчерпан на 80% (на 68% – после окончания make world). Это притом, что мой world собирался чуть ли не в минимальной конфигурации – практически все, что можно запретить в /etc/make.conf, было запрещено. Так что, похоже, 512 Мбайт – необходимый минимум для mfs в /usr/obj.
Очевидно, что даже при гигабайтном ОЗУ отвести такое его количество под mfs на постоянной основе – излишество нехорошее. Так что лучше монтировать файловую систему /usr/obj только по мере надобности – непосредственно перед пересборкой <<мира>> и ядра:
размонтируя ее по завершении (впрочем, пересборка ядра все равно потребует перезагрузки, и mfs в /usr/obj пропадет естественным образом).