UMGUM.COM (лучше) 

NAS ( Построение простейшей распределённой расширяемой сетевой горизонтальной файловой системы с использованием технологий MDADM, LVM, NFS и MHDDFS. )

18 сентября 2012  (обновлено 17 июля 2019)

Эта публикация отнесена в архив. Она неактуальна.

OS: "Linux Debian 5/6/7 (Lenny/Squeeze/Wheezy)".

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

Условия: используемое программное обеспечение должно быть бесплатным, свободно распространяемым, имеющим стабильную версию, не требующим внесения изменений в коде операционной системы и не запрашивающим специального оборудования.

Особое условие: работа сетевой распределённой системы должна быть понятна от начала и до конца при развёртывании даже не высококвалифицированному специалисту; не должна выглядеть эдаким "чёрным ящиком" для обслуживающего персонала. В общем, нужно сделать так, чтобы каждый этап развёртывания и сопровождения системы был понятен и максимально прост.

Для достижения поставленной цели применим решение из нескольких этапов:

1. MDADM будет обеспечивать зеркалирование разделов физических дисков;
2. Блочные устройства, полученные от MDADM, сводятся в единое пространство с помощью LVM;
3. Единое блочное устройство, полученное от LVM, форматируется под файловую систему XFS;
4. Файловые системы публикуются в сеть с помощью NFS;
5. На стороне эксплуатирующего ресурсы сервера файловые системы, полученные по NFS, монтируются и объединяются в единое доступное пространство с помощью MHDDFS.

Очерёдность отрабатывания такая:

1. При запуске подсистем хранилища проверяем, все ли HDD, с серийными номерами перечисленными в специальном списке, корректно запустились и готовы к работе;
2. Запускаем RAID и проверяем корректность запуска.
3. Собираем LVM.
4. Монтируем локальную файловую систему с LVM и публикуем её посредством NFS.
5. Собираем полученные по NFS файловые системы единую точку с помощью MHDDFS.


После нескольких лет эксплуатации построенной на FUSE MHDDFS стало ясно, что эта прослойка сырая (не зря разработчик её откровенно забросил в 2012-м, и никто не взялся поддерживать проект далее) и отбирающая слишком много (в десять раз больше чем NFS, лежащий на уровне ниже; на четырёх-ядерном "Intel Xeon" в работе "бутерброда" из NFS и MHDDFS первый забирает 1-2% CPU, а второй - 25%, ограничивая после такой утилизации рост скорости обмена данными с дисковым устройством) ресурсов при работе с файловыми системами. Помогает выдача MHDDFS более высокого приоритета с помощью "nice -n -1" - это позволяет ему отрабатывать задачи быстрее и компенсирует внутреннюю ошибку логики, при которой на медленных задачах MHDDFS отбирает нерационально много системных ресурсов. Ещё при монтировании файловых систем предназначенных именно для хранения файлов есть смысл отключить кеширование запросов, указав в опциях "-o direct_io", что позволит снизить накладные расходы при запросах потокового чтения и записи больших файлов.

Однако любые пляски с отключением кеша и повышением приоритета MHDDFS не дают действительно хороших результатов: обращение в удалённому ресурсу NFS даёт скорость в рамках возможностей сети (110-120MBps для гигабитной), а обращение к этому ресурсу, сведённому в единую точку MHDDFS показывает скорость не выше 5-10MBps на один поток - провальные показатели.

Через пару дней тестов выявилась схема, при которой MHDDFS перестаёт быть узким местом: нужно выключить для FUSE кеширование (direct_io) и журналирование событий в log-файл - как ни забавно, провальная производительность была вызвана тем, что я включил журналирование событий на уровне отладки, надеясь выявить в потоке сообщений проблему. И конечно, дать возможность FUSE работать асинхронно (async). Теперь MHDDFS пишет на диск со скоростью этого самого диска.

Как оказалось, MHDDFS и NFS совершенно не умеют согласовывать сведения о текущем состоянии файловых систем. Например, если в один из подразделов, сведённых в единую точку MHDDFS, осуществлять запись напрямую, мимо виртуальной FS MHDDFS, то в один не прекрасный момент связка MHDDFS и NFS вульгарно зависнет. Получается, что единственно стабильный вариант работы - только через точку монтирования MHDDFS, а скорость при этом смехотворная. Я бы даже вынес в описание технологии замечание ни в коем случае не работать с разделами объединёнными MHDDFS напрямую, всегда делая это через общую точку входа - во избежание практически гарантированного в таком случае зависания связки MHDDFS и NFS.

Тесты с использованием более свежей "unionfs-fuse" показали несколько большую скорость записи в собранную файловую систему, по сравнению с MHDDFS - в районе 15-25MBps - при этом потребление ресурсов самой прослойкой "unionfs-fuse" минимально (в районе 2-10%, при том что MHDDFS отъедал на в два раза меньших скоростях до 25% CPU), и на первое место в "disk-IO" вышел NFS, отбирающий себе все свободные ресурсы - надо полагать, что теперь он стал узким местом. Однако скорости всё равно не сопоставимы с реальными задачами регулярного сохранения сотен гигабайт данных. Кроме того у "unionfs-fuse" отсутствует важнейшее умение MHDDFS - резервирование лимита оставшегося места на диске и автоматическое перемещение файлов на другой раздел при достижении указанного лимита.

Следующие реализации "простых" хранилищ надёжнее будет сделать на AUFS - но её модуль уже несколько лет никак не включают в основное ядро "Linux" (не зря, надо полагать - хотя истинной причины я не знаю).

Как вариант можно попробовать BTRFS, которая поддерживает склеивание и зеркалирование.

Можно делать на "MDADM + iSCSI + LVM + XFS", но проблема в том, что из проверенных технологий только MHDDFS собирает и пересобирает в единую точку уже готовые автономные файловые системы, позволяя в тоже время обращаться к каждой по отдельности, снижая тем самым риски потери информации при выходе из строя отдельных файловых систем - остальные технологии не рассматривают итоговую FS как автономные куски и потеря целостности всей системы может повредить сразу все данные.

При конфигурировании MHDDFS следует учитывать то, что собирается она из отдельных кусков файловых систем ограниченного размера. Для файлового хранилища объектов фиксированного размера эта особенность непринципиальна, но вот при использовании в системе резервного копирования выявляются нюансы, требующие контроля в процессе эксплуатации. Суть в том, что MHDDFS распределяет файлы последовательно, и единственный критерий, по которому она будет укладывать файл в тот или иной (по очерёдности монтирования) кусок файловой системы - это исходный размер файла и свободное место на диске за вычетом значения специального параметра MHDDFS "mlimit". Проблема в том, что системы резервного копирования вначале работы создают файл минимального размера, который после может разрастись до сотен Гигабайт или Терабайт. Практический пример: мы указали, что на диск можно записывать данные до момента, когда на нём не останется всего 10 Гигабайт свободного пространства; MHDDFS при свободных 100 Гигабайтах создаёт файл контейнера резервного копирования размером в 1 Мегабайт и начинает туда записывать данные объёмом до 4 терабайт - что невозможно заранее проконтролировать, кроме как ручным приблизительным рассчётом исходя из объёмом подлежащих резервному копированию файлов (в реальности постоянно изменяющихся, в том числе и в размерах). Да, MHDDFS пытается "прозрачно для приложений" переместить файл на другой кусок файловой системы, размер которого достаточен - но если в этот момент в файл активно ведётся запись, то вероятнее всего через пару часов или дней мы получим "zombie"-процесс, который даже не остановишь. В общем, это проблема, которая отчасти решается профилактикой и плановым распределением файлов резервных копий по участкам файловой системы достаточных размеров.

Возможно имеет смысл сразу переходить на распределённую FS вроде "Ceph", но на 2012-2015 годы в ней отсутствуют средства мониторинга и локализации проблем - так что на сегодняшний день, по словам её разработчиков, "CephFS" в качестве файловой системы могут использовать, либо очень крутые и храбрые, либо очень глупые.

MDADM, как и файловая система XFS, которую мы будем использовать, активно журналирует изменения, отвлекая ресурсы задействованных в массивах HDD. Потому будет хорошей идеей вынести журналы на HDD, не используемый непосредственно в схеме хранения. Обслуживание каждого тома MDADM задействует по одному журнальному файлу, который очень желательно вынести на нежурналируемую файловую систему, например EXT2. С XFS такой фокус не пройдёт - она не может работать с обычным файлом, требуя блочное устройство для самостоятельного создания на нём журнала. Можно было бы натравить драйвер XFS на специально созданное для него "loopback" блочное устройство в файловой системе на HDD, не задействованном в схеме хранения, но смысл в этом есть только тогда, когда мы захотим поизощрённее потратить ресурсы сервера. Гораздо проще создать на HDD, не задействованном в схеме хранения, раздел, который отдать XFS для размещения на нём журнала.

На всех компьютерах в схеме очень и очень желательно иметь высокоскоростные сетевые интерфейсы, например "GigabitEthernet". Лучше использовать сетевые карты с поддержкой "Jumbo frames" в количестве от двух штук. Желательно хороший коммутатор с поддержкой "Jumbo frames" и "Link aggregation". Подключение на коммутаторе конфигурируем с поддержкой "Jumbo frames" и "Link aggregation", на каждом сервере минимум по два порта - хороший канал и передача данных крупными блоками очень поспособствуют быстрой работе.

Переход к настройке автоматизации процедур сборки и разборки распределённой файловой системы.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )