Как стать автором
Обновить

Неприкрытая ZFS

Время на прочтение 11 мин
Количество просмотров 3.1K
Автор оригинала: David Chisnall
Когда в Sun проектировали ZFS, они выбросили сборник правил и создали нечто, не имеющее прямых аналогов в любой другой UNIX-подобной системе. David Chisnall рассмотрел какие изменения обычных моделей хранения произвели, какие основы заложены в систему, и как это все совмещается друг с другом.



Каждые несколько лет, кто-то делает предсказание относительно того, как много частных компьютерных ресурсов, вероятно, потребуется в будущем. Позже, все смеются над собой, над тем насколько наивны они были. В проектировании ZFS Sun попыталась избежать данной ошибки.

Пока весь мир переходит на 64-битные файловые системы, Sun внедряет 128-битную файловую систему. Придем ли мы когда-нибудь к необходимости в таких больших размерах? Не сразу. Масса планеты Земля приблизительно равна 6*10^24 кг. Если бы мы взяли соответствующую массу водорода, то у нас бы получилось 3.6*10^48 атомов. 128-битная файловая система может индексировать 2^128, или 10^38 блоков размещения информации. Если вы построите хранилище, в котором каждый атом хранится как единичный бит водорода (не считая места, которое вам необходимо для управляющей логики), вы можете построить около 300000 превышающих массу Земли устройств, если каждое из них будет иметь 128-битную файловую систему с 4Кб блоками размещения данных. Мы построим жесткие диски размером с континенты, прежде чем достигнем пределов пространства ZFS.

Так есть ли какой либо смысл в 128-битной файловой системе? Не совсем. Однако, если текущие тенденции продолжатся, мы начнем достигать пределов 64-битных файловых систем в ближайшие 5-10 лет. Возможно, хватило бы 80-битной файловой системы для иных непредвиденных ограничений, могущих стать причиной замены до того, как закончится пространство, но большинству компьютеров оперировать с 80-битными числами сложнее чем со 128-битными. Поэтому Sun выпустила 128-битную систему.



Тупоконечная независимость



Когда вы записываете данные на диск (или в сеть), вы должны быть осторожны с порядком байтов. Если вы загружаете и храните данные только на одной машине, вы можете выписать содержимое машинных регистров независимо от их представления. Проблемы начинаются когда вы начинаете делится данными. Все, что меньше байта – без проблем (если только вам не посчастливилось использовать VAX), но большие объемы требуют использования четко определенного порядка байт.

Два наиболее распространенных порядка названы в философов-яйцеедов из книги Джонатана Свифта «Путешествия Гулливера». «Тупоконечная» (big-endian) нотация располагает байты в виде 1234 в то время как «остроконечные» (little-endian) компьютеры хранят их в порядке 4321. Некоторые компьютеры используют что-то вроде 1324, но в основном, люди стараются этого избежать.

Большинство файловых систем спроектированы для работы на определенной архитектуре. Хотя, если бы даже она и была в дальнейшем портирована на другую архитектуру, каждая файловая система стремится хранить метаданные в том байтовом порядке, в котором их хранит родная для файловой системы архитектура. HFS+ от Apple является хорошим примером подобной практики. С тех пор, как HFS+ возникла на PowerPC, структуры данных в файловой системе хранятся в формате big-endian. На Mac на базе Intel вы должны переворачивать байтовый порядок каждый раз, когда вы загружаете или пишете данные на диск. Инструкция BSWAP на чипах x86 позволяет быстрый переворот, но, в любом случае, это не слишком хорошо для производительности.

Sun оказалась в интересном положении, когда пришла к порядку расположения байто, когда начала продажи и поддержку Solaris на архитектурах SPARC64 и x86-64. SPARC64 – big-endian, и x86-64 – little-endian; какое бы ни выбрала Sun решение, она сделала бы одну из своих файловых систем медленнее, чем на другой поддерживаемой Sun архитектуре.

Решение Sun? Не выбирать. Каждая структура данных в ZFS записана в том байтовом порядке, в каком компьютер её записал, вместе с флагом, показывающим, какой байтовый порядок был использован. Раздел ZFS на Opteron будет little-endian, а контролируемый UltraSPARC — big-endian. Если вы разделите диск между двумя машинами, все по-прежнему будет работать – и чем больше вы будете записывать, тем больше он будет оптимизирован для естественного чтения.

Вопиющее нарушение уровневой структуры



ZFS была описана в Linux Kernel Mailing List как «ужасное нарушение уровневой структуры». Это не совсем точно, ZFS не файловая система в традиционном смысле UNIX, но, скорее всего набор определенных слоев, который предоставляет расширенный набор обычной файловой системы. В этом месте любым администраторам VMS в аудитории разрешают чувствовать себя самодовольным и бормотать себе: «UNIX наконец-то получил настоящую файловую систему. Может быть, он, наконец, готов в промышленному использованию».

Три слоя ZFS называются: слой интерфейса, слой транзакционных объектов и слой объединенного хранилища. Проходя вниз по стеку, эти слои преображают запросы файловой системы в объектные транзакции, транзакции в операции с виртуальными блочными устройствами, и, наконец, виртуальные операции в реальные.

Некоторые части этого стека являются необязательными, как мы увидим позже.

Менеджер разделов.



Внизу стека ZFS находится слой объединенного хранилища. Этот слой играет роль, похожую на менеджер разделов на существующей системе.

Каждое виртуальное устройство (vdev), созданное комбинированием устройств, используя один из вариантов — зеркалирование или RAID-Z. Однажды создав vdev-ы, вы соединяете их в пул хранилища. Этот подход обеспечивает некоторую гибкость. Если у вас есть некоторые данные, доступ к которым должен быть быстрым и некоторые, которые должны надежно храниться, вы можете создать сильно зеркалируемый пул и пул RAID-Z, и создать файловые системы на том, который вам больше подходит. Учтите, что файловые системы не должны размещаться непрерывно на vdev; несмотря на то, что они могут казаться последовательными блоками пространства хранилища на верхних уровнях, они вообще могут быть неблизкими.

Одна из ключевых идей проектирования ZFS заключалась в том, что создание раздела должно быть таким же простым, как создание директории. Например, это дает возможность применять квоты в ZFS, дав каждому пользователю собственный раздел для домашней директории, который будет расти динамически в пуле хранения.

В отличие от других менеджеров разделов, ZFS определяет планирование I/O. Каждая транзакция имеет определенный приоритет и временные рамки, которые планировщик обрабатывает на vdev-уровне системы.

Объектный слой



Средним слоем ZFS является слой транзакционных объектов. Основой этого слоя является Data Management Unit (DMU) (модуль управления данными) и на многих блочных диаграммах ZFS DMU это все, что вы увидите в этом слое. DMU предоставляет объекты для верхнего слоя и позволяет выполнение атомарных операций.

Если у вас когда-либо происходил сбой питания во время записи файла, возможно, вы запускали fsck, scandisk или что-нибудь подобное. В конце концов, у вас, вероятно, останутся некоторые испорченные файлы. Если это были текстовые файлы, то вам, может быть, повезло; повреждение может быть устранено легко. В ином случае, если файлы имели смешанную структуру, вы могли потерять целый файл. Приложения баз данных решают эту проблему используя механизм транзакций; они записывают что-то на диск, говоря «Я собираюсь это сделать», и делают это. Затем они пишут «Я это сделал» в лог. Если где-то в процессе что-то пойдет не так, база данных может просто откатиться назад, к состоянию перед началом операции.

Многие новые файловые системы используют журналирование, которое делает те же вещи, что и базы данных на уровне файловой системы. Преимущество журналирования в том, что состояние файловой системы всегда целостное; после сбоя питания, вам всего лишь надо воспроизвести журнал, а не сканировать весь диск. К сожалению, эта целостность не распространяется на файлы. Если вы производите две операции записи из пользовательского приложения, возможно, что одна будет завершена, в то время как другая — нет. Эта модель является причиной некоторых проблем.

ZFS использует транзакционную модель. Вы можете начать транзакцию, произведя некоторое количество записей, и они либо все завершатся успешно, либо все неуспешно. Это возможно потому, что ZFS использует механизм копирование-на-записи. Каждый раз, записывая некоторые данные, ZFS записывает эти данные в запасное место диска. Затем, она обновляет метаданные, говоря «Это новая версия». Если процесс записи не достигнет стадии обновления метаданных, ничего из старых данных не будет перезаписано.

Одна из сторон эффекта копирование-на-записи заключается в том, что это позволяет создавать постоянные снапшоты. Некоторые файловые системы, такие, как UFS2 на FreeBSD и XFS на IRIX, уже поддерживают снапшоты, так что это не новая концепция. Стандартная технология – это создание раздела снапшотов. Один раз сделав снапшот, каждая операция записи заменяется последовательностью, которая копирует оригинал на раздел снапшота, и, затем выполняет запись. Излишне будет напоминать, что данный подход весьма дорогой.

С ZFS, все, что вам нужно для создания снапшота — это увеличить количество ссылок раздела. Каждая операция записи уже недеструктивна, и единственное, что может произойти — это то, что операция обновления метаданных не сможет удалить ссылки на старое местоположение. Другая сторона эффекта от использования этого механизма заключается в том, что снапшоты являются первоклассными файловыми системами со своими собственными правами. Вы можете делать запись на снапшот точно так же, как и на любой другой раздел. Например, вы можете создать снапшот файловой системы для каждого пользователя и разрешить им делать на нем все, что они захотят, без воздействия на других пользователей. Эта возможность особенно полезна в сочетании с Solaris Zones.

Претендуя на файловую систему



Все это прекрасно, иметь базирующуюся на объектах, транзакционную систему хранения данных, но кто собирается ее использовать? Все мои приложения хотят общаться с чем-то, что очень похоже на файловую систему UNIX. И тут в дело вступает ZPL, POSIX слой в ZFS. ZPL производит преобразование между файловыми операциями POSIX (read, write и т.д.) и находящимися ниже операциями DMU. Он отвечает за управление структурой директорий и позволяет использование ACL (списков контроля доступа).

Вдобавок к ZPL, в ZFS есть другой модуль в слое интерфейса, известный как ZVOL. Этот слой выполняет более простое преобразование; вместо того чтобы создавать видимость POSIX-совместимой файловой системы, он кажется необработанным блочным устройством, которое полезно для реализации существующих файловых систем, опирающихся на пулы хранения ZFS. Порт FreeBSD изначально использует существующую файловую систему UFS2 поверх ZVOL-устройства. Мне кажется, что порт Apple будет использовать HFS+ поверх ZVOL для того, чтобы позволить Apple поддерживать метаданные HFS+.

Доступны некоторые интригующие возможности для будущей работы в этом слое. Поскольку ZFS уже поддерживает транзакции, возможно, что SQL или похожий интерфейс может быть использован в этом слое. Исходя из низкой стоимости создания файловых систем, каждый пользователь может создать базы данных на лету и получить гораздо более гибкий интерфейс, чем предоставляемый слоем POSIX. Проблема Microsoft WinFS – слишком трудно заставить каждого поддерживать подход, который не был основан на файлах – не будет применяться, так как средство увеличило бы, а не заменило бы текущую файловую систему.

Что она не делает?



В настоящее время, наибольшим недостатком ZFS является недостаток шифрования.

NTFS имеет пофайловое шифрование, и у большинства менеджеров разделов имеются механизмы шифрования на блочном уровне. К счастью, на эту проблему обратили внимание, и ZFS может использовать тот же механизм, что применяется для сжатия.

Четко определяемые квоты также не поддерживаются. Вы можете создавать расширяемые разделы с максимальным размером, но вы не можете установить максимальное число файлов, которое пользователь может создать в разделе.

Последнее слово в RAID?



Одно из самых волнующих возможностей ZFS — это RAID-Z. Современный жесткий диск это устройство с довольно скучным интерфейсом. Это массив, состоящий из блоков фиксированного размера, который может быть прочитан или записан. С тех пор, как RAID обычно реализуется похоже на блочный слой (часто на уровне аппаратного обеспечения, прозрачно для операционной системы), устройства RAID также предоставляют этот интерфейс. В массиве RAID-5 с тремя дисками, запись блока вызывает сохранение блока на диск 1, а результат XOR-а блока, соответственно, один из дисков 2 или 3. Это вызывает две взаимосвязанных проблемы:

  • Если вы счастливчик, вы можете гарантировать выполнение атомарных операций записи на один диск, но почти невозможно получить возможность атомарной записи на группу дисков. Если что-то нарушится между записью первого блока и контрольной суммой, система будет содержать бессмыслицу для этого блочного индекса на всех дисках. Современные RAID-контроллеры обходят эту проблему путем хранения записей в энергонезависимой RAM до момента получения подтверждения от диска о том, что данные были безопасно сохранены.
  • В вышеупомянутом сценарии, записывание одного блока на диск 1 требует, чтобы вы затем считали блок с диска 2 и сохранили контрольную сумму на диск 3. Эта дополнительная операция чтения посереди каждой записи может быть дорогой.


Так что же RAID-Z делает иначе? Во-первых, массив RAID-Z не настолько туп, как массив RAID; у него есть некоторая осведомленность о том, что в нем хранится. Ключевая составляющая — переменная ширина страйпа(!). С существующими реализациями RAID, она составляет либо 1 байт (например, каждый нечетный байт будет записан на диск 1, каждый четный — на диск 2, а каждый байт четности — на диск 3), либо размер блока. В ZFS размер страйпа определяется размером записи. Каждый раз, когда вы производите запись на диск, вы записываете страйп целиком.

Такое строение решает обе проблемы, упомянутые выше. С тех пор, как ZFS транзакционна, страйп либо записывается корректно и метаданные обновляются, либо нет. Если аппаратные средства терпят неудачу при промежуточной записи, то это значит, что запись не удалась, однако существующие данные на диске не будут затронуты. Проще говоря, поскольку страйп содержит только записываемые данные, вам никогда не понадобится считывать что-то с диска для осуществления записи.

RAID-Z стал возможен только за счет новой структуры слоев ZFS. Вы можете восстановить раздел RAID-5, когда диск сломается, и сказать:«XOR всех битов на индексе 0 на каждом диске в сумме дает 0, так что должен содержать наш пропавший диск?». С RAID-Z это невозможно. Вместо этого, вам надо будет пройтись по метаданным файловой системы. Контроллер RAID, который является блочным устройством не будет иметь возможности это сделать. Один из дополнительных бонусов это то, что аппаратный контроллер RAID при запросе на восстановление, должен воссоздать диск – даже те блоки, которые не использовались, в то время как RAID-Z нужно восстановить только использовавшиеся блоки.

Не являясь частью RAID-Z, ZFS включает в себя ещё одну возможность, которая помогает решить проблемы потери данных: так как каждый блок содержит хеш SHA256, поврежденный сектор на диске будет отображаться, как содержащий ошибки, даже если котроллер диска этого не замечает. Это преимущество перед существующими реализациями RAID. Например, используя RAID-5, вы можете восстановить целый раздел, но если одиночный сектор на диске поврежден, весь диск может сообщить о существующей ошибке. Раздел RAID-Z может сообщить вам, какой диск содержит ошибку (тот, чей блок не соответствует хешу) и восстановить данные с другого. Это также служит ранним предупреждением, о том, что диск возможно поврежден.

Со всем этим переменным размером страйпа, вам, возможно, будет интересно, что происходит, когда размер страйпа меньше, чем единичный блок. Ответ прост: вместо вычисления четности, ZFS просто зеркалирует данные.

Есть одна вещь, которую я нашел крайне интересной в ZFS — то, что она будет работать лучше на блочном устройстве, у которого меньшая стоимость случайных считываний. Почти как если бы у проектировщиков были флешки, вместо жестких дисков, в их понимании.

Как я могу это получить?



Будет ли ZFS доступна для вашей операционной системы? Для пользователей [Open]Solaris ответ будет «да», для остальных — «может быть». Если вы используете Windows, то возможно нет. Для Linux ситуация несколько сложнее. Реализация OpenSolaris выпускается под лицензией CDDL, с которой GPL не совместима. Существует две возможности поддержки этой файловой системы на Linux. Первая – это сделать полностью собственную реализацию, что потребует огромных усилий и поэтому вряд ли произойдет в ближайшее время. Другая – это портировать ZFS во FUSE и запускать, как пользовательский процесс. Эта работа уже производится, но, похоже, что результат будет значительно медленнее версии, реализованная на уровне ядра и невозможно будет использовать на загрузочных разделах. Пользователи Ubuntu, желающие поддержки ZFS, могут переключиться на Nexenta, в которой используется ядро OpenSolaris и пользовательское окружение GNU.

До тех пор, пока CDDL – пофайловая лицензия, она не влияет на общую лицензию проекта, что позволяет использовать её в большом количестве любых проектов, у которых нет лицензии, указывающей, что «все компоненты этого проекта должны быть защищены лицензией, соблюдающей эти условия». Это включает FreeBSD и DragonFlyBSD, обе из которых имеют разработки портов, и MacOS X — следующая версия которой, ожидается, будет поставляться с поддержкой ZFS.
Теги:
Хабы:
+26
Комментарии 12
Комментарии Комментарии 12

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн
PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн