X
  • ZFS
    June 11, 2008

Сквозная целостность данных в ZFS

Guest Author
Работу любой файловой системы
можно свести к следующему: на просьбу прочитать блок данных, она должна
вернуть те же самые данные, которые были ранее записаны в этот блок.
Если этого сделать не получается -- из-за отключения диска, повреждения
данных и т.д. -- она должна обнаружить это и вернуть ошибку.

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

Даже если предположить, что все диски
идеальны и всегда возвращают то, что было записано ранее, данные все
ещё будут уязвимы при передаче: ошибки в микрокоде контроллера, ошибки
четности при DMA и т.д. Мы могли бы говорить только о том, что данные
были целы, когда покидали пластину диска. Если рассматривать данные как
посылку, это все равно что UPS говорила бы: "Мы гарантируем, что ваша
посылка не была повреждена, когда мы приняли её". Это не совсем та
гарантия, которая нам нужна.

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

Безосновательно
дорогие массивы хранения данных не могут решить эту проблему. Путь
прохождения операций ввода/вывода не только остаётся таким же уязвимым,
но и становится длиннее: покидая пластину диска, данные должны уцелеть,
несмотря на какие бы то ни было аппаратные и программно-аппаратные
ошибки, которые могут содержаться в массиве.

А если ваш массив находится в SAN, вы используете сеть, спроектированную писателями микрокода дисков. Бог в помощь.

Что
же делать? Одним из вариантов является сохранение контрольной суммы
каждого блока на диске. Большинство современных дисковых накопителей
могут быть отформатированы с размером сектора, который немного больше
стандартных 512 байт -- обычно 520 или 528. Эти дополнительные байты
можно использовать для хранения контрольной суммы блока. Сказать легко,
но правильно использовать контрольную сумму сложнее: эфективность
контрольной суммы крайне зависит от места хранения и момента проверки.

Во многих дисковых массивах (типичный пример с прекрасным описанием данного метода можно найти в статье о Dell|EMC PowerVault) данные сравниваются с контрольной суммой внутри массива.
К сожалению, это не очень помогает справиться с проблемой. Такой способ
не позволяет выявить типичные ошибки в микрокоде диска, такие как,
например, фантомная запись (операция записи, которая не достигла диска,
но была подтверждена как выполненная), так как данные и контрольная
сумма хранятся вместе -- они непротиворечивы, даже если диск возвращает
устаревшие данные. Да и весь путь ввода-вывода, который должны пройти
данные от момена прочтения с пластины диска до момента попадания в
память сервера (и наоборот) остается незащищенным. Короче говоря, такой
вариант использования контрольной суммы блока есть лишь хороший способ
убедиться в том, что надёжность массива ничуть не ниже надёжности
дисков, в нём содержащихся, но не более того.

Способ
использования контрольной суммы блока, применяемый NetApp, выглядит
похоже, но на самом деле намного мощнее. Как и во многих других
массивах, NetApp форматирует диски с секторами по 520 байт. Затем они
группируются в блоки по 8 секторов: 4Кб данных (размер блока файловой
системы WAFL) и 64 байта контрольной суммы. Когда система WAFL читает
блок, данные сравниваются с контрольной суммой, как и в случае с
массивом из предыдущего примера, но с ключевым отличием: сравнение
происходит после того, как данные прошли весь путь
ввода-вывода, что позволяет удостовериться в том, что блок прошел путь
от пластины диска до памяти без повреждения.

Это существенное
улучшение, но и его недостаточно. Контрольная сумма на уровне блока
только доказывает, что блок цел сам по себе; она не доказывает, что это
правильный блок. Повторяя нашу аналогию с UPS: "Мы гарантируем, что
посылка, которую вы получили, цела. Но мы не гарантируем, что это ваша
посылка."

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

Аутентификация данных в ZFS

Сквозная целостность данных требует проверки каждого блока данных с использованием независимой контрольной суммы, после
прибытия данных в память. Недостаточно знать, что каждый блок является
сам собой, или что он был корректен в какой-то момент прохождения по
пути ввода/вывода в прошлом. Наша цель - выявлять любые возможные формы
повреждения, включая такие человеческие ошибки, как использование диска
с файловой системой в качестве области подкачки, или опечатки в
аргументах команды dd(1). (Не приходилось ли вам место когда-нибудь
вместо "if=" ввести "of="?)

Пул дисковой памяти в ZFS -
это, на самом деле, дерево блоков. ZFS обеспечивает изоляцию сбоев
между данными и контрольной суммой за счет хранения контрольной суммы
каждого блока в указателе, указывающем на этот блок
(указателе-родителе) -- а не в самом блоке. Каждый блок дерева содержит
контрольные суммы всех "детей", таким образом, весь пул оказывается
самоверифицирующимся. [Вершина иерархии - убер-блок (uberblock, корень
дерева) - особый случай, так как он не имеет родителя; о том, как мы
обращаемся с ним, поговорим в отдельной заметке.]

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

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

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

Но и это еще не всё!

Блоки пула дисковой памяти ZFS образуют дерево Меркле,
в котором каждый блок проверяет всех своих "детей". Было доказано, что
дерево Меркле обеспечивает криптографически стойкую аутнтификацию как
для каждого компонента дерева, так и для всего дерева целиком. ZFS
использует 256-битную контрольную сумму (алгоритм SHA-256) для каждого
блока (метаданных) и проддерживает алгоритмы вычисления контрольных
сумм для пользовательских данных начиная с простого и быстрого
алгоритма fletcher2 (используемого по умолчанию) до медленного, но
безопасного SHA-256.
При использовании для пользовательских данных криптографически стойкого
хеша, такого как SHA-256, контрольная сумма убер-блока является
постоянно обновляющимся крипто-хэшем для всех данных в пуле.

А это будет очень удобно, если вам потребуется обратиться в UPS для пересылки пула.


Теги Technorati:

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.