Распределенная файловая система GFS (Google File System). Компьютерные сети и технологии: Печать

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

Важно понимать различие между файловым сервисом и файловым сервером. Файловый сервис – это описание функций, которые файловая система предлагает своим пользователям. Это описание включает имеющиеся примитивы, их параметры и функции, которые они выполняют. С точки зрения пользователей файловый сервис определяет то, с чем пользователи могут работать, но ничего не говорит о том, как все это реализовано. В сущности, файловый сервис определяет интерфейс файловой системы с клиентами.

Файловый сервер – это процесс, который выполняется на отдельной машине и помогает реализовывать файловый сервис. В системе может быть один файловый сервер или несколько, но в хорошо организованной распределенной системе пользователи не знают, как реализована файловая система. В частности, они не знают количество файловых серверов, их месторасположение и функции. Они только знают, что если процедура определена в файловом сервисе, то требуемая работа каким-то образом выполняется, и им возвращаются требуемые результаты. Более того, пользователи даже не должны знать, что файловый сервис является распределенным. В идеале он должен выглядеть также, как и в централизованной файловой системе.

Так как обычно файловый сервер – это просто пользовательский процесс (или иногда процесс ядра), выполняющийся на некоторой машине, в системе может быть несколько файловых серверов, каждый из которых предлагает различный файловый сервис. Например, в распределенной системе может быть два сервера, которые обеспечивают файловые сервисы систем UNIX и MS-DOS соответственно, и любой пользовательский процесс пользуется подходящим сервисом.

Файловый сервис в распределенных файловых системах (впрочем как и в централизованных) имеет две функционально различные части: собственно файловый сервис и сервис каталогов. Первый имеет дело с операциями над отдельными файлами, такими, как чтение, запись или добавление, а второй – с созданием каталогов и управлением ими, добавлением и удалением файлов из каталогов и т.п.



Для любого файлового сервиса, независимо от того, централизован он или распределен, самым главным является вопрос, что такое файл? Во многих системах, таких как UNIX и MS DOS, файл – это неинтерпретируемая последовательность байтов. Значение и структура информации в файле является заботой прикладных программ, операционную систему это не интересует.

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

Важным аспектом файловой модели является возможность модификации файла после его создания. Обычно файлы могут модифицироваться, но в некоторых распределенных системах единственными операциями с файлами являются СОЗДАТЬ и ПРОЧИТАТЬ. Такие файлы называются неизменяемыми. Для неизменяемых файлов намного легче осуществить кэширование файла и его репликацию (тиражирование), так как исключается все проблемы, связанные с обновлением всех копий файла при его изменении.

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

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

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

Принципиальной проблемой, связанной со способами именования файлов, является обеспечение прозрачности. В данном контексте прозрачность понимается в двух слабо различимых смыслах. Первый – прозрачность расположения – означает, что имена не дают возможности определить месторасположение файла. Например, имя /server1/dir1/ dir2/x говорит, что файл x расположен на сервере 1, но не указывает, где расположен этот сервер. Сервер может перемещаться по сети, а полное имя файла при этом не меняется. Следовательно, такая система обладает прозрачностью расположения.

В системах, состоящих из клиентов и серверов, потенциально имеется четыре различных места для хранения файлов и их частей: диск сервера, память сервера, диск клиента (если имеется) и память клиента. Наиболее подходящим местом для хранения всех файлов является диск сервера. Он обычно имеет большую емкость, и файлы становятся доступными всем клиентам. Кроме того, поскольку в этом случае существует только одна копия каждого файла, то не возникает проблемы согласования состояний копий.

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

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

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

Во-вторых, необходимо определить правило замены данных при заполнении кэш-памяти. Здесь можно использовать любой стандартный алгоритм кэширования, например, алгоритм LRU (least recently used), соответствии с которым вытесняется блок, к которому дольше всего не было обращения.

Кэш-память на сервере легко реализуется и совершенно прозрачна для клиента. Так как сервер может синхронизировать работу памяти и диска, с точки зрения клиентов существует только одна копия каждого файла, так что проблема согласования не возникает.

Pr0grammer 29 октября 2009 в 01:31

Распределенная файловая система GFS (Google File System)

  • Разработка веб-сайтов

В настоящее время, в условиях роста информации, возникают задачи хранения и обработки данных очень большого объема. Поэтому эти данные обрабатывается сразу на нескольких серверах одновременно, которые образуют кластеры. Для упрощения работы с данными на кластерах и разрабатывают распределенные файловые системы. Мы подробно рассмотрим пример распределенной файловой системы Google File System , используемую компанией Google . (Статья является, фактически, вольным и урезанным переводом оригинальной статьи).

GFS является наиболее, наверное, известной распределенной файловой системой. Надежное масштабируемое хранение данных крайне необходимо для любого приложения, работающего с таким большим массивом данных, как все документы в интернете. GFS является основной платформой хранения информации в Google . GFS - большая распределенная файловая система, способная хранить и обрабатывать огромные объемы информации.
GFS строилась исходя из следующим критериев:

  • Система строится из большого количества обыкновенного недорого оборудования, которое часто дает сбои. Должны существовать мониторинг сбоев, и возможность в случае отказа какого-либо оборудования восстановить функционирование системы.
  • Система должна хранить много больших файлов. Как правило, несколько миллионов файлов, каждый от 100 Мб и больше. Также часто приходится иметь дело с многогигабайтными файлами, которые также должны эффективно храниться. Маленькие файлы тоже должны храниться, но для них не оптимизируется работа системы.
  • Как правило, встречаются два вида чтения: чтение большого последовательного фрагмента данных и чтение маленького объема произвольных данных. При чтении большого потока данных обычным делом является запрос фрагмента размером в 1Мб и больше. Такие последовательные операции от одного клиента часто читают подряд идущие куски одного и того же файла. Чтение небольшого размера данных, как правило, имеет объем в несколько килобайт. Приложения, критические по времени исполнения, должны накопить определенное количество таких запросов и отсортировать их по смещению от начала файла. Это позволит избежать при чтении блужданий вида назад-вперед.
  • Часто встречаются операции записи большого последовательного куска данных, который необходимо дописать в файл. Обычно, объемы данных для записи такого же порядка, что и для чтения. Записи небольших объемов, но в произвольные места файла, как правило, выполняются не эффективно.
  • Система должна реализовывать строго очерченную семантику параллельной работы нескольких клиентов, в случае если они одновременно пытаются дописать данные в один и тот же файл. При этом может случиться так, что поступят одновременно сотни запросов на запись в один файл. Для того чтобы справится с этим, используется атомарность операций добавления данных в файл, с некоторой синхронизацией. То есть если поступит операция на чтение, то она будет выполняться, либо до очередной операции записи, либо после.
  • Высокая пропускная способность является более предпочтительной, чем маленькая задержка. Так, большинство приложений в Google отдают предпочтение работе с большими объемами данных, на высокой скорости, а выполнение отдельно взятой операции чтения и записи, вообще говоря, может быть растянуто.
Файлы в GFS организованы иерархически, при помощи каталогов, как и в любой другой файловой системе, и идентифицируются своим путем. С файлами в GFS можно выполнять обычные операции: создание, удаление, открытие, закрытие, чтение и запись.
Более того, GFS поддерживает резервные копии, или снимки (snapshot). Можно создавать такие резервные копии для файлов или дерева директорий, причем с небольшими затратами.

Архитектура GFS

Рисунок взят из оригинальной статьи.

В системе существуют мастер-сервера и чанк-сервера, собственно, хранящие данные. Как правило, GFS кластер состоит из одной главной машины мастера (master) и множества машин, хранящих фрагменты файлов чанк-серверы (chunkservers). Клиенты имеют доступ ко всем этим машинам. Файлы в GFS разбиваются на куски - чанки (chunk, можно сказать фрагмент). Чанк имеет фиксированный размер, который может настраиваться. Каждый такой чанк имеет уникальный и глобальный 64 - битный ключ, который выдается мастером при создании чанка. Чанк-серверы хранят чанки, как обычные Linux файлы, на локальном жестком диске. Для надежности каждый чанк может реплицироваться на другие чанк-серверы. Обычно используются три реплики.
Мастер отвечает за работу с метаданными всей файловой системы. Метаданные включают в себя пространства имен, информацию о контроле доступа к данным, отображение файлов в чанки, и текущее положение чанков. Также мастер контролирует всю глобальную деятельность системы такую, как управление свободными чанками, сборка мусора (сбор более ненужных чанков) и перемещение чанков между чанк-серверами. Мастер постоянно обменивается сообщениями (HeartBeat messages) с чанк-серверами, чтобы отдать инструкции, и определить их состояние (узнать, живы ли еще).
Клиент взаимодействует с мастером только для выполнения операций, связанных с метаданными. Все операции с самими данными производятся напрямую с чанк-серверами. GFS - система не поддерживает POSIX API, так что разработчикам не пришлось связываться с VNode уровнем Linux.
Разработчики не используют кеширование данных, правда, клиенты кешируют метаданные. На чанк-серверах операционная система Linux и так кеширует наиболее используемые блоки в памяти. Вообще, отказ от кеширования позволяет не думать о проблеме валидности кеша (cache coherence).

Мастер

Использование одного мастера существенно упрощает архитектуру системы. Позволяет производить сложные перемещения чанков, организовывать репликации, используя глобальные данные. Казалось бы, что наличие только одного мастера должно являться узким местом системы, но это не так. Клиенты никогда не читают и не пишут данные через мастера. Вместо этого они спрашивают у мастера, с каким чанк-сервером они должны контактировать, а далее они общаются с чанк-серверами напрямую.
Рассмотрим, как происходит чтение данных клиентом. Сначала, зная размер чанка,
имя файла и смещение относительно начала файла, клиент определяет номер чанка внутри файла. Затем он шлет запрос мастеру, содержащий имя файла и номер чанка в этом файле. Мастер выдает чанк-серверы, по одному в каждой реплике, которые хранят нужный нам чанк. Также мастер выдает клиенту идентификатор чанка.
Затем клиент решает, какая из реплик ему нравится больше (как правило та, которая ближе), и шлет запрос, состоящий из чанка и смещения относительно начала чанка. Дальнейшее чтения данных, не требует вмешательства мастера. На практике, как правило, клиент в один запрос на чтение включает сразу несколько чанков, и мастер дает координаты каждого из чанков в одном ответе.
Размер чанка является важной характеристикой системы. Как правило, он устанавливается равным 64 мегабайт, что гораздо больше, чем размер блока в обычной файловой системе. Понятно, что если необходимо хранить много файлов, размеры которых меньше размера чанка, то будем расходоваться много лишней памяти. Но выбор такого большого размера чанка обусловлен задачами, которые приходится компании Google решать на своих кластерах. Как правило, что-то считать приходится для всех документов в интернете, и поэтому файлы в этих задачах очень большого размера.

Метаданные

Мастер хранит три важных вида метаданных: пространства имен файлов и чанков, отображение файла в чанки и положение реплик чанков. Все метаданные хранятся в памяти мастера. Так как метаданные хранятся в памяти, операции мастера выполняются быстро. Состояние дел в системе мастер узнает просто и эффективно. Он выполняется сканирование чанк-серверов в фоновом режиме. Эти периодические сканирования используются для сборки мусора, дополнительных репликаций, в случае обнаружения недоступного чанк-сервера и перемещение чанков, для балансировки нагрузки и свободного места на жестких дисках чанк-серверов.
Мастер отслеживает положение чанков. При старте чанк-сервера мастер запоминает его чанки. В процессе работы мастер контролирует все перемещения чанков и состояния чанк-серверов. Таким образом, он обладает всей информацией о положении каждого чанка.
Важная часть метаданных - это лог операций. Мастер хранит последовательность операций критических изменений метаданных. По этим отметкам в логе операций, определяется логическое время системы. Именно это логическое время определяет версии файлов и чанков.
Так как лог операций важная часть, то он должен надежно храниться, и все изменения в нем должны становиться видимыми для клиентов, только когда изменятся метаданные. Лог операций реплицируется на несколько удаленных машин, и система реагирует на клиентскую операцию, только после сохранения этого лога на диск мастера и диски удаленных машин.
Мастер восстанавливает состояние системы, исполняя лог операций. Лог операций сохраняет относительно небольшой размер, сохраняя только последние операции. В процессе работы мастер создает контрольные точки, когда размер лога превосходит некоторой величины, и восстановить систему можно только до ближайшей контрольной точки. Далее по логу можно заново воспроизвести некоторые операции, таким образом, система может откатываться до точки, которая находится между последней контрольной точкой и текущем временем.

Взаимодействия внутри системы

Выше была описана архитектура системы, которая минимизирует вмешательства мастера в выполнение операций. Теперь же рассмотрим, как взаимодействуют клиент, мастер и чанк-серверы для перемещения данных, выполнения атомарных операций записи, и создания резервной копии (snapshot).
Каждое изменение чанка должно дублироваться на всех репликах и изменять метаданные. В GFS мастер дает чанк во владение (lease) одному из серверов, хранящих этот чанк. Такой сервер называется первичной (primary) репликой. Остальные реплики объявляются вторичными (secondary). Первичная реплика собирает последовательные изменения чанка, и все реплики следуют этой последовательности, когда эти изменения происходят.
Механизм владения чанком устроен таким образом, чтобы минимизировать нагрузку на мастера. При выделении памяти сначала выжидается 60 секунд. А затем, если потребуется первичная реплика может запросить мастера на расширение этого интервала и, как правило, получает положительный ответ. В течение этого выжидаемого периода мастер может отменить изменения.
Рассмотрим подробно процесс записи данных. Он изображен по шагам на рисунке, при этом тонким линиям соответствуют потоки управления, а жирным потоки данных.


Этот рисунок также взят из оригинальной статьи.
  1. Клиент спрашивает мастера, какой из чанк-серверов владеет чанком, и где находится этот чанк в других репликах. Если необходимо, то мастер отдает чанк кому-то во владение.
  2. Мастер в ответ выдает первичную реплику, и остальные (вторичные) реплики. Клиент хранит эти данные для дальнейших действий. Теперь, общение с мастером клиенту может понадобиться только, если первичная реплика станет недоступной.
  3. Далее клиент отсылает данные во все реплики. Он может это делать в произвольном порядке. Каждый чанк-сервер будет их хранить в специальном буфере, пока они не понадобятся или не устареют.
  4. Когда все реплики примут эти данные, клиент посылает запрос на запись первичной реплике. В этом запросе содержатся идентификация данных, которые были посланы в шаге 3. Теперь первичная реплика устанавливает порядок, в котором должны выполняться все изменения, которые она получила, возможно от нескольких клиентов параллельно. И затем, выполняет эти изменения локально в этом определенном порядке.
  5. Первичная реплика пересылает запрос на запись всем вторичным репликам. Каждая вторичная реплика выполняет эти изменения в порядке, определенном первичной репликой.
  6. Вторичные реплики рапортуют об успешном выполнении этих операций.
  7. Первичная реплика шлет ответ клиенту. Любые ошибки, возникшие в какой-либо реплике, также отсылаются клиенту. Если ошибка возникла при записи в первичной реплике, то и запись во вторичные реплики не происходит, иначе запись произошла в первичной реплике, и подмножестве вторичных. В этом случае клиент обрабатывает ошибку и решает, что ему дальше с ней делать.
Из примера выше видно, что создатели разделили поток данных и поток управления. Если поток управления идет только в первичную реплику, то поток данных идет во все реплики. Это сделано, чтобы избежать создания узких мест в сети, а взамен широко использовать пропускную способность каждой машины. Так же, чтобы избежать узких мест и перегруженных связей, используется схема передачи ближайшему соседу по сетевой топологии. Допустим, что клиент передает данные чанк-серверам S1 ,..., S4 . Клиент шлет ближайшему серверу данные, пусть S1 . Он далее пересылает ближайшему серверу, пусть будет S2 . Далее S2 пересылает их ближайшему S3 или S4 , и так далее.
Также задержка минимизируется за счет использования конвейеризации пакетов передаваемых данных по TCP . То есть, как только чанк-сервер получил какую-то часть данных, он немедленно начинает их пересылать. Без сетевых заторов, идеальное время рассылки данных объемом B байт на R реплик будет B/T + RL , где T сетевая пропускная способность, а L - задержка при пересылке одного байта между двумя машинами.
GFS поддерживает такую операцию, как атомарное добавление данных в файл. Обычно, при записи каких-то данных в файл, мы указываем эти данные и смещение. Если несколько клиентов производят подобную операцию, то эти операции нельзя переставлять местами (это может привести к некорректной работе). Если же мы просто хотим дописать данные в файл, то в этом случае мы указываем только сами данные. GFS добавит их атомарной операцией. Вообще говоря, если операция не выполнилась на одной из вторичных реплик, то GFS , вернет ошибку, а данные будут на разных репликах различны.
Еще одна интересная вещь в GFS - это резервные копии (еще можно сказать мгновенный снимок) файла или дерева директорий, которые создаются почти мгновенно, при этом, почти не прерывая выполняющиеся операции в системе. Это получается за счет технологии похожей на сopy on write . Пользователи используют эту возможность для создания веток данных или как промежуточную точку, для начала каких-то экспериментов.

Операции, выполняемые мастером

Мастер важное звено в системе. Он управляет репликациями чанков: принимает решения о размещении, создает новые чанки, а также координирует различную деятельность внутри системы для сохранения чанков полностью реплицированными, балансировки нагрузки на чанк-серверы и сборки неиспользуемых ресурсов.
В отличие от большинства файловых систем GFS не хранит состав файлов в директории. GFS логически представляет пространство имен, как таблицу, которая отображает каждый путь в метаданные. Такая таблица может эффективно храниться в памяти в виде бора (словаря этих самых путей). Каждая вершина в этом дереве (соответствует либо абсолютному пути к файлу, либо к директории) имеет соответствующие данные для блокировки чтения и записи(read write lock). Каждое операция мастера требует установления некоторых блокировок. В этом месте в системе используются блокировки чтения-записи. Обычно, если операция работает с /d1/d2/.../dn/leaf , то она устанавливает блокировки на чтение на /d1, /d1/d2, ..., d1/d2/.../dn и блокировку, либо на чтение, либо на запись на d1/d2/.../dn/leaf . При этом leaf может быть как директорией, так и файлом.
Покажем на примере, как механизм блокировок может предотвратить создание файла /home/user/foo во время резервного копирования /home/user в /save/user . Операция резервного копирования устанавливает блокировки на чтение на /home и /save , а так же блокировки на запись на /home/user и /save/user . Операция создания файла требует блокировки на чтение /home и /home/user , а также блокировки на запись на /home/user/foo . Таким образом, вторая операция не начнет выполняться, пока не закончит выполнение первая, так как есть конфликтующая блокировка на /home/user . При создании файла не требуется блокировка на запись родительской директории, достаточно блокировки на чтение, которая предотвращает удаление этой директории.
Кластеры GFS , являются сильно распределенными и многоуровневыми. Обычно, такой кластер имеет сотни чанк-серверов, расположенных на разных стойках. Эти сервера, вообще говоря, доступны для большого количества клиентов, расположенных в той же или другой стойке. Соединения между двумя машинами из различных стоек может проходить через один или несколько свитчей. Многоуровневое распределение представляет очень сложную задачу надежного, масштабируемого и доступного распространения данных.
Политика расположения реплик старается удовлетворить следующим свойствам: максимизация надежности и доступности данных и максимизация использование сетевой пропускной способности. Реплики должны быть расположены не только на разных дисках или разных машинах, но и более того на разных стойках. Это гарантирует, что чанк доступен, даже если целая стойка повреждена или отключена от сети. При таком расположении чтение занимает время приблизительно равное пропускной способности сети, зато поток данных при записи должен пройти через различные стойки.
Когда мастер создает чанк, он выбирает где разместить реплику. Он исходит из нескольких факторов:
  • Желательно поместить новую реплику на чанк-сервер с наименьшей средней загруженностью дисков. Это будет со временем выравнивать загруженность дисков на различных серверах.
  • Желательно ограничить число новых создаваемых чанков на каждом чанк-сервере. Несмотря на то, что создание чанка сама по себе быстрая операция, она подразумевает последующую запись данных в этот чанк, что уже является тяжелой операцией, и это может привести к разбалансировке объема трафика данных на разные части системы.
  • Как сказано выше, желательно распределить чанки среди разных стоек.
Как только число реплик падает ниже устанавливаемой пользователем величины, мастер снова реплицирует чанк. Это может случиться по нескольким причинам: чанк-сервер стал недоступным, один из дисков вышел из строя или увеличена величина, задающая число реплик. Каждому чанку, который должен реплицироваться, устанавливается приоритет, который тоже зависит от нескольких факторов. Во-первых, приоритет выше у того чанка, который имеет наименьшее число реплик. Во-вторых, чтобы увеличить надежность выполнения приложений, увеличивается приоритет у чанков, которые блокируют прогресс в работе клиента
Мастер выбирает чанк с наибольшим приоритетом и копирует его, отдавая инструкцию одному из чанк-серверов, скопировать его с доступной реплики. Новая реплика располагается, исходя из тех же причин, что и при создании.
Во время работы мастер постоянно балансирует реплики. В зависимости от распределения реплик в системе, он перемещает реплику для выравнивания загруженности дисков и балансировки нагрузки. Также мастер должен решать, какую из реплик стоит удалить. Как правило, удаляется реплика, которая находится на чанк-сервере с наименьшим свободным местом на жестких дисках.
Еще одна важная функция, лежащая на мастере - это сборка мусора. При удалении файла, GFS не требует мгновенного возвращения освободившегося дискового пространства. Он делает это во время регулярной сборки мусора, которая происходит как на уровне чанков, так и на уровне файлов. Авторы считают, что такой подход делает систему более простой и надежной.
При удалении файла приложением, мастер запоминает в логах этот факт, как и многие другие. Тем не менее, вместо требования немедленного восстановления освободившихся ресурсов, файл просто переименовывается, причем в имя файла добавляется время удаления, и он становится невидимым пользователю. А мастер, во время регулярного сканирования пространства имен файловой системы, реально удаляет все такие скрытые файлы, которые были удалены пользователем более трех дней назад (этот интервал настраивается). А до этого момента файл продолжает находиться в системе, как скрытый, и он может быть прочитан или переименован обратно для восстановления. Когда скрытый файл удаляется мастером, то информация о нем удаляется также из метаданных, а все чанки этого файла отцепляются от него.
Мастер помимо регулярного сканирования пространства имен файлов делает аналогичное сканирование пространства имен чанков. Мастер определяет чанки, которые отсоединены от файла, удаляет их из метаданных и во время регулярных связей с чанк-серверами передает им сигнал о возможности удаления всех реплик, содержащих заданный чанк. У такого подхода к сборке мусора много преимуществ, при одном недостатке: если место в системе заканчивается, а отложенное удаление увеличивает неиспользуемое место, до момента самого физического удаления. Зато есть возможность восстановления удаленных данных, возможность гибкой балансировки нагрузки при удалении и возможность восстановления системы, в случае каких-то сбоев.

Устойчивость к сбоям и диагностика ошибок

Авторы системы считают одной из наиболее сложных проблем частые сбои работы компонентов системы. Количество и качество компонентов делают эти сбои не просто исключением, а скорее нормой. Сбой компонента может быть вызван недоступностью этого компонента или, что хуже, наличием испорченных данных. GFS поддерживает систему в рабочем виде при помощи двух простых стратегий: быстрое восстановление и репликации.
Быстрое восстановление - это, фактически, перезагрузка машины. При этом время запуска очень маленькое, что приводит к маленькой заминке, а затем работа продолжается штатно. Про репликации чанков уже говорилось выше. Мастер реплицирует чанк, если одна из реплик стала недоступной, либо повредились данные, содержащие реплику чанка. Поврежденные чанки определяется при помощи вычисления контрольных сумм.
Еще один вид репликаций в системе, про который мало было сказано - это репликация мастера. Реплицируется лог операций и контрольные точки (checkpoints). Каждое изменение файлов в системе происходит только после записи лога операций на диски мастером, и диски машин, на которые лог реплицируется. В случае небольших неполадок мастер может перезагрузиться. В случае проблем с жестким диском или другой жизненно важной инфраструктурой мастера, GFS стартует нового мастера, на одной из машин, куда реплицировались данные мастера. Клиенты обращаются к мастеру по DNS, который может быть переназначен новой машине. Новый мастер является тенью старого, а не точной копией. Поэтому у него есть доступ к файлам только для чтения. То есть он не становится полноценным мастером, а лишь поддерживает лог операций и другие структуры мастера.
Важной частью системы является возможность поддерживать целостность данных. Обычный GFS кластер состоит из сотен машин, на которых расположены тысячи жестких дисков, и эти диски при работе с завидным постоянством выходят из строя, что приводит к порче данных. Система может восстановить данные с помощью репликаций, но для этого необходимо понять испортились ли данные. Простое сравнение различных реплик на разных чанк-серверах является неэффективным. Более того, может происходить несогласованность данных между различными репликами, ведущая к различию данных. Поэтому каждый чанк-сервер должен самостоятельно определять целостность данных.
Каждый чанк разбивается на блоки длиной 64 Кбайт . Каждому такому блоку соответствует 32 -битная контрольная сумма. Как и другие метаданные эти суммы хранятся в памяти, регулярно сохраняются в лог, отдельно от данных пользователя.
Перед тем как считать данные чанк-сервер проверяет контрольные суммы блоков чанка, которые пересекаются с затребованными данными пользователем или другим чанк-сервером. То есть чанк-сервер не распространяет испорченные данные. В случае несовпадения контрольных сумм, чанк-сервер возвращает ошибку машине, подавшей запрос, и рапортует о ней мастеру. Пользователь может считать данные из другой реплики, а мастер создает еще одну копию из данных другой реплики. После этого мастер дает инструкцию этому чанк-серверу об удалении этой испорченной реплики.
При добавлении новых данных, верификация контрольных сумм не происходит, а для блоков записывается новые контрольные суммы. В случае если диск испорчен, то это определится при попытке чтения этих данных. При записи чанк-сервер сравнивает только первый и последний блоки, пересекающиеся с границами, в которые происходит запись, поскольку часть данных на этих блоках не перезаписывается и необходимо проверить их целостность.

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

Назначение и возможности DFS

Распределенная файловая система DFS (Distributed File System ) появилась как стандартный компонент еще в Win2k. Ее задача – облегчить управление, доступ и поиск данных в сети. Для этого файловые ресурсы, находящиеся на разных компьютерах, объединяются в единое логическое пространство имен. Пользователь, вместо того чтобы запоминать имена всех общих сетевых ресурсов (Universal Naming Convention, UNC), вроде \\Server\Folder, будет обращаться к единому пространству UNC-имен, в котором объединены все серверы и общие ресурсы сети. А на каком конкретно компьютере находится запрашиваемый файл, уже забота DFS , пользователю не нужно беспокоиться о реальном расположении файла. При обращении клиента он просто перебрасывается на нужный ему каталог. На месте источника, на который указывает ссылка, может быть любая операционная система, к ресурсам которой можно обратиться, используя UNC (Windows, Linux, xBSD, NetWare). Физические объекты, связанные ссылками с DFS , называются целевыми объектами (targets) или репликами (replics).

Но удобство для пользователей и администраторов – далеко не самое важное из основных преимуществ DFS . Дело в том, что с одним логическим именем может быть связано несколько общих ресурсов, в которых хранится идентичная информация. Такой набор альтернативных общих ресурсов, связанных с одним логическим именем DFS , называется набором реплик. И если общие ресурсы находятся в одном пространстве доменного корня DFS и располагаются на серверах Win2k или Win2k3, есть возможность настроить автоматическую синхронизацию информации между ними. Пользователь, обратившийся к DFS , обычно перенаправляется к ближайшей реплике, и если она не доступна, он будет перенаправлен к альтернативному ресурсу. Для уменьшения нагрузки на сервер DFS на стороне клиента данные кэшируются, поэтому при частом обращении к одному и тому же ресурсу каждый запрос к DFS не производится. Таким образом, автоматическое резервирование важной информации , реализованное в DFS , еще и повышает отказоустойчивость всей системы (выход одного сервера или дискового устройства не повлияет на работу пользователей). Хотя следует помнить, что DFS не создавалась для работы часто с обновляющимися данными, и особенно для тех случаев, когда файл одновременно может обновляться в нескольких местах (в DFS остается та версия файла, где были внесены последние изменения).

В реализации DFS в Win2k можно было разместить только одно пространство имен, в Win2k3 их может быть уже несколько. В Win2k3 R2 появилась новая версия этой системы – DFS Namespaces , в которой многие вопросы уже решены. За репликацию данных в Win2k3 SP1 и SP2 отвечает FRS (File Replication Server ), в Win2k3 R2 – DFS Replicatio n. Главным их отличием является то, что в FRS самым маленьким объектом, подлежащим репликации, является файл, в DFS Replication используется более развитая технология RDC (Remote Differential Compression ), которая умеет копировать только изменившиеся части файла, а функция cross-file RDC меньше нагружает канал при копировании новых файлов. Таким образом, использование DFS еще и уменьшает нагрузку на сеть, что особенно актуально для удаленных офисов с недостаточной пропускной способностью. В службе DFS не используется никаких дополнительных средств обеспечения безопасности. При обращении к targets проверяются только права доступа файловой системы и установленные для этих объектов разрешения в каталоге Active Directory.

Эти разные корни

Начальной точкой для всех имен дерева DFS служит корень распределенной файловой системы. Фактически корень – это некоторый общий ресурс, находящийся на сервере, все остальные логические имена системы DFS будут подключаться как следующий иерархический уровень. Корни в DFS могут быть двух видов, каждый отличается способами хранения данных и возможностями. Изолированный (автономный) корень (Standalone DFS ) не связан с Active Directory, и все ссылки на сетевые ресурсы хранятся в реестре самого сервера DFS . Такой корень не использует DFS Replication , то есть не предполагает дублирование информации на другие ресурсы, и поэтому не обеспечивает отказоустойчивость. При выходе из строя сервера DFS вся иерархия становится не доступной, хотя пользователи могут обращаться к ресурсам напрямую. К слову, несколько Standalone DFS серверов способны работать в кластере, поэтому эта проблема может быть решена. Если сервер DFS является членом домена, используется доменный корень (Domain-based DFS ). При таком варианте можно подключать несколько реплик и использовать DFS Replication для репликации как самого корня, так и ссылок DFS . Если в Domain-based DFS корни находятся на компьютерах под управлением Win2k и Win2k3, то такой корень называется “Mixed mode domain DFS “.

При доменном DFS вся информация о пространстве имен находится на контроллере домена, к которому периодически обращается сервер DFS . Учитывая синхронизацию между DFS в домене, которая становится все более сложной при каждом изменении структуры, эти запросы могут быть узким местом в системе, поэтому в этом случае также есть некоторые ограничения. Так в Win2k существовало ограничение на 16 корней для одного пространства имен. В Win2k3 это ограничение снято, так как сервер DFS теперь может обращаться к любому DC, а не только к эмулятору PDC. Второе ограничение доменных корней связано с тем, что вся структура хранится в специальном объекте, который также необходимо дублировать на всех DC при любом малейшем изменении в структуре DFS . В документации рекомендуется ограничивать максимальный размер объекта 5-тью Мб, что приблизительно соответствует 5000 ссылкам (каталогам). Эта величина зависит от многих параметров, длины имени ссылок, наличия и размера комментариев, которые также хранятся в этом объекте. Но в среднем DFS редко когда превышает 50-100 ссылок, и после первоначальной настройки она остается в основном статичной, а значит, часто дублироваться не будет, и этих ограничений достигнуть просто не удастся. Кстати, в будущей Windows 2008 ограничение в 5000 ссылок уже снято, но для этого все серверы должны работать под управлением Longhorn. Для Standalone DFS рекомендованный лимит ссылок на порядок выше и составляет 50000 ссылок .

Настройка DFS

Для примера настроим DFS на компьютере под управлением Win2k3 с SP2, все настройки в SP1 аналогичны. В настройках DFS в R2 и Win2k есть некоторые отличия, но не настолько глобальные, чтобы не разобраться самостоятельно. Все управление распределенной файловой системой выполняется централизованно с помощью оснастки MMC “Распределенная файловая система DFS “, которую можно вызвать во вкладке “Администрирование” Панели управления Windows. С ее помощью можно создавать и удалять корни, подключаться к любым корням DFS . Удобно, что в одной вкладке может отображаться несколько корней DFS . В случае работы корня в “Mixed mode domain DFS “, то есть когда реплики и корни DFS располагаются на компьютерах под управлением разных версий Windows, управление DFS необходимо производить с компьютера, работающего под Win2k3. Как вариант, можно установить пакет Win2k3 Administration Tools Pack (adminpak.msi), который лежит в свободном доступе на сайте корпорации. В этом случае для управления можно использовать и компьютеры с WinXP. Информацию по этому пакету найдешь по адресу support.microsoft.com/kb/304718 . Кроме этого, для работы с DFS также можно использовать утилиты командной строки dfscmd.exe и dfsutil.exe. Последняя имеет больше возможностей, но по умолчанию не включена в состав операционной системы, чтобы ее использовать, необходимо установить пакет Win2k3 Support Tools. Обрати внимание, что для успешной установки Support Tools требуется скачать два файла: suptools.msi и support.cab.

Для создания нового корня вызываем оснастку, щелкаем мышкой по заголовку и в контекстном меню выбираем “Создать корень” (New Root), как вариант, можно выбрать аналогичный пункт в меню “Действие”. Появляется Мастер создания нового корня (New Root Wizard), следуем его подсказкам. На втором шаге выбираем тип создаваемого корня (доменный или изолированный), указываем несущий домен и сервер. После проверки соединения с выбранным сервером вводим имя корня. Обрати внимание, как будет выглядеть UNC путь к новому корню, по умолчанию \\server\nameshare. Так как на данный момент общего каталога не существует, на следующем шаге нужно выбрать локальный каталог, который будет использоваться в качестве общего. Этот каталог не содержит реальных данных, в нем будут находиться ссылки, указывающие на физическое расположение данных. Мастер создает ресурсы, разрешающие чтение и выполнение членам группы Пользователи. При необходимости следует скорректировать разрешения. Теперь нажимаем кнопку Готово, новый корень появится в окне консоли. Если сервер работает под управлением Win2k3, аналогичным образом создаем и другие корни. С помощью команды Проверить статус (Check Status), вызываемую из меню консоли или контекстного меню, можно проверить состояние реплики. Состояние будет указано в одноименном столбце и рядом с именем появится кружок с отметкой. Если она зеленого цвета, значит, все нормально. Для проверки можно зайти по указанному UNC или использовать на локальном компьютере команду «net share» или «net view computer_name» с удаленного. Команда «dfsutil /Root:\\server\share /View» покажет информацию о DFS .

>dfsutil /Root:\\server.com\first /View
DFS Utility Version 5.2 (built on 5.2.3790.3959)
Domain Root with 0 Links
Root Name="\\SERVER\first" Comment="first Root" State="1" Timeout="300"
Target Server="GRINDERS" Folder="first" State="2"

После создания корня его можно опубликовать в Active Directory. Для этого в контекстном меню выбираем Свойства, переходим на вкладку Публикация и устанавливаем флажок “Опубликовать этот корень в Active Directory”. Доменные корни публикуются автоматически и в обязательном порядке.

Создание ссылок

После создания корня можно начинать подключать общие ресурсы. Для чего в том же контекстном меню выбираем пункт Создать ссылку (New Link). В появившемся окне “Новая ссылка”, в поле “Имя ссылки”, вводим имя ссылки, под которым она будет доступна в DFS, затем чуть ниже UNC-путь к целевому каталогу (должен уже существовать). Для поиска общих ресурсов можно использовать кнопку Обзор, чуть ниже можно изменить время кэширования этой ссылки для клиентов DFS (по умолчанию 1800 сек). По окончании нажимаем кнопку ОК. Команда «dfsutil /view» должна показать состояние всех подключенных ссылок и их свойства. Если в сети работает несколько серверов, есть возможность добавить реплику, указывающую на альтернативную ссылку. Реплика на корень или отдельный объект создается аналогично, только в первом случае в контекстном меню выбираем пункт “Создать корневую целевую папку”, а во втором – “Создать папку”.

Общие ресурсы, с которыми будет производиться репликация, должны располагаться в разделах с файловой системой NTFS на компьютерах, работающих под управлением серверных версий Windows от 2000 (лучше 2003). В поле “Путь к целевой общей папке” появившегося окна вводим или при помощи кнопки Обзор указываем общий ресурс, располагающийся на другом компьютере. В том случае если для синхронизации информации между этими ресурсами планируется использовать альтернативные программы (или синхронизация будет производиться вручную), следует снять флажок “Добавить эту целевую папку к набору репликации” (Add this target to the replication set). Нажимаем ОК, и появляется Мастер настройки репликации (Configure Replication Wizard), который поможет выбрать мастер-реплику и топологию репликации. На первом шаге указываем каталог, который будет использоваться в качестве основного целевого, вся информация из этого каталога затем будет скопирована в другую папку. Последняя должна быть пустой, если в ней есть файлы, они будут скопированы во временный каталог, а затем удалены. Если общий ресурс по каким-либо причинам не подходит для репликации (например, расположен не в разделе с NTFS), он будет отмечен красным крестиком, при попытке перейти к следующему шагу мастер предложит указать другую ссылку или закончить работу.

Нажатием кнопки “Промежуточное хранение ” (Staging Folder ) можно изменить расположение каталога, который будет использоваться для временного хранения реплицируемых данных. По умолчанию этот каталог размещается в разделе, отличном от того, на котором находится общий ресурс, связанный с DFS . Далее мастер предложит выбрать топологию репликации. Необходимо будет указать один из следующих вариантов:

  • Кольцо (Ring) - все реплики обмениваются информацией с двумя соседними;
  • Звезда (Hub and spoke) - указывается основная ссылка, с которой и будут обмениваться информацией все остальные реплики;
  • Полная сетка (Mesh) - все реплики обмениваются друг с другом;
  • Особая (Custom) - позднее администратор самостоятельно настроит репликацию для каждой пары серверов.

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

После создания реплики для ссылки соответствующий ей значок в окне оснастки изменится. В контекстном меню также появятся два новых пункта: Отобразить/Скрыть статус репликации и Остановить репликацию. В поле статуса репликации может быть один из трех результатов. Если процесс репликации завершен нормально, на значках будут зеленые флажки. Красный крестик на значке реплики укажет, что она в данный момент недоступна, в поле Состояние подпись изменится на Автономный. Если в проверяемой ссылке недоступны лишь некоторые реплики, в значке появится желтый восклицательный знак.

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

Если выбранный вариант топологии репликации по каким-либо причинам не подошел, топологию репликации впоследствии можно легко изменить, выбрав окно свойств соответствующей ссылки и перейдя на вкладку Репликация. Здесь находятся еще несколько полезных настроек. По умолчанию репликация выполняется постоянно, нажав кнопку Расписание, можно изменить расписание репликаций для всех подключений. Чуть ниже указываются фильтры для файлов и подпапки, которые не будут реплицироваться. Для этого нажимаем Изменить и вводим шаблоны файлов или подкаталогов.

Для принудительной репликации информации, хранящейся на определенном сервере, можно воспользоваться утилитой NtfrsUtl.exe, которая входит в состав пакета Support Tools . Команда проста: «ntfrsutl poll /now server.com». Чтобы увидеть установленные временные интервалы, через которые производится репликация, следует ввести «ntfrsutl poll». Все установки доступны по команде «ntfrsutl sets server.com».

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

Администратору для контроля следует почаще заглядывать в журнал “Администрирование – Просмотр событий – Служба репликации файлов”, где можно найти информацию обо всех событиях, происходящих со службой FRS.

В настоящее время, в условиях роста информации, возникают задачи хранения и обработки данных очень большого объема. Поэтому эти данные обрабатывается сразу на нескольких серверах одновременно, которые образуют кластеры. Для упрощения работы с данными на кластерах и разрабатывают распределенные файловые системы. Мы подробно рассмотрим пример распределенной файловой системы Google File System , используемую компанией Google . (Статья является, фактически, вольным и урезанным переводом оригинальной статьи).

GFS является наиболее, наверное, известной распределенной файловой системой. Надежное масштабируемое хранение данных крайне необходимо для любого приложения, работающего с таким большим массивом данных, как все документы в интернете. GFS является основной платформой хранения информации в Google . GFS - большая распределенная файловая система, способная хранить и обрабатывать огромные объемы информации.
GFS строилась исходя из следующим критериев:

  • Система строится из большого количества обыкновенного недорого оборудования, которое часто дает сбои. Должны существовать мониторинг сбоев, и возможность в случае отказа какого-либо оборудования восстановить функционирование системы.
  • Система должна хранить много больших файлов. Как правило, несколько миллионов файлов, каждый от 100 Мб и больше. Также часто приходится иметь дело с многогигабайтными файлами, которые также должны эффективно храниться. Маленькие файлы тоже должны храниться, но для них не оптимизируется работа системы.
  • Как правило, встречаются два вида чтения: чтение большого последовательного фрагмента данных и чтение маленького объема произвольных данных. При чтении большого потока данных обычным делом является запрос фрагмента размером в 1Мб и больше. Такие последовательные операции от одного клиента часто читают подряд идущие куски одного и того же файла. Чтение небольшого размера данных, как правило, имеет объем в несколько килобайт. Приложения, критические по времени исполнения, должны накопить определенное количество таких запросов и отсортировать их по смещению от начала файла. Это позволит избежать при чтении блужданий вида назад-вперед.
  • Часто встречаются операции записи большого последовательного куска данных, который необходимо дописать в файл. Обычно, объемы данных для записи такого же порядка, что и для чтения. Записи небольших объемов, но в произвольные места файла, как правило, выполняются не эффективно.
  • Система должна реализовывать строго очерченную семантику параллельной работы нескольких клиентов, в случае если они одновременно пытаются дописать данные в один и тот же файл. При этом может случиться так, что поступят одновременно сотни запросов на запись в один файл. Для того чтобы справится с этим, используется атомарность операций добавления данных в файл, с некоторой синхронизацией. То есть если поступит операция на чтение, то она будет выполняться, либо до очередной операции записи, либо после.
  • Высокая пропускная способность является более предпочтительной, чем маленькая задержка. Так, большинство приложений в Google отдают предпочтение работе с большими объемами данных, на высокой скорости, а выполнение отдельно взятой операции чтения и записи, вообще говоря, может быть растянуто.
Файлы в GFS организованы иерархически, при помощи каталогов, как и в любой другой файловой системе, и идентифицируются своим путем. С файлами в GFS можно выполнять обычные операции: создание, удаление, открытие, закрытие, чтение и запись.
Более того, GFS поддерживает резервные копии, или снимки (snapshot). Можно создавать такие резервные копии для файлов или дерева директорий, причем с небольшими затратами.

Архитектура GFS

Рисунок взят из оригинальной статьи.

В системе существуют мастер-сервера и чанк-сервера, собственно, хранящие данные. Как правило, GFS кластер состоит из одной главной машины мастера (master) и множества машин, хранящих фрагменты файлов чанк-серверы (chunkservers). Клиенты имеют доступ ко всем этим машинам. Файлы в GFS разбиваются на куски - чанки (chunk, можно сказать фрагмент). Чанк имеет фиксированный размер, который может настраиваться. Каждый такой чанк имеет уникальный и глобальный 64 - битный ключ, который выдается мастером при создании чанка. Чанк-серверы хранят чанки, как обычные Linux файлы, на локальном жестком диске. Для надежности каждый чанк может реплицироваться на другие чанк-серверы. Обычно используются три реплики.
Мастер отвечает за работу с метаданными всей файловой системы. Метаданные включают в себя пространства имен, информацию о контроле доступа к данным, отображение файлов в чанки, и текущее положение чанков. Также мастер контролирует всю глобальную деятельность системы такую, как управление свободными чанками, сборка мусора (сбор более ненужных чанков) и перемещение чанков между чанк-серверами. Мастер постоянно обменивается сообщениями (HeartBeat messages) с чанк-серверами, чтобы отдать инструкции, и определить их состояние (узнать, живы ли еще).
Клиент взаимодействует с мастером только для выполнения операций, связанных с метаданными. Все операции с самими данными производятся напрямую с чанк-серверами. GFS - система не поддерживает POSIX API, так что разработчикам не пришлось связываться с VNode уровнем Linux.
Разработчики не используют кеширование данных, правда, клиенты кешируют метаданные. На чанк-серверах операционная система Linux и так кеширует наиболее используемые блоки в памяти. Вообще, отказ от кеширования позволяет не думать о проблеме валидности кеша (cache coherence).

Мастер

Использование одного мастера существенно упрощает архитектуру системы. Позволяет производить сложные перемещения чанков, организовывать репликации, используя глобальные данные. Казалось бы, что наличие только одного мастера должно являться узким местом системы, но это не так. Клиенты никогда не читают и не пишут данные через мастера. Вместо этого они спрашивают у мастера, с каким чанк-сервером они должны контактировать, а далее они общаются с чанк-серверами напрямую.
Рассмотрим, как происходит чтение данных клиентом. Сначала, зная размер чанка,
имя файла и смещение относительно начала файла, клиент определяет номер чанка внутри файла. Затем он шлет запрос мастеру, содержащий имя файла и номер чанка в этом файле. Мастер выдает чанк-серверы, по одному в каждой реплике, которые хранят нужный нам чанк. Также мастер выдает клиенту идентификатор чанка.
Затем клиент решает, какая из реплик ему нравится больше (как правило та, которая ближе), и шлет запрос, состоящий из чанка и смещения относительно начала чанка. Дальнейшее чтения данных, не требует вмешательства мастера. На практике, как правило, клиент в один запрос на чтение включает сразу несколько чанков, и мастер дает координаты каждого из чанков в одном ответе.
Размер чанка является важной характеристикой системы. Как правило, он устанавливается равным 64 мегабайт, что гораздо больше, чем размер блока в обычной файловой системе. Понятно, что если необходимо хранить много файлов, размеры которых меньше размера чанка, то будем расходоваться много лишней памяти. Но выбор такого большого размера чанка обусловлен задачами, которые приходится компании Google решать на своих кластерах. Как правило, что-то считать приходится для всех документов в интернете, и поэтому файлы в этих задачах очень большого размера.

Метаданные

Мастер хранит три важных вида метаданных: пространства имен файлов и чанков, отображение файла в чанки и положение реплик чанков. Все метаданные хранятся в памяти мастера. Так как метаданные хранятся в памяти, операции мастера выполняются быстро. Состояние дел в системе мастер узнает просто и эффективно. Он выполняется сканирование чанк-серверов в фоновом режиме. Эти периодические сканирования используются для сборки мусора, дополнительных репликаций, в случае обнаружения недоступного чанк-сервера и перемещение чанков, для балансировки нагрузки и свободного места на жестких дисках чанк-серверов.
Мастер отслеживает положение чанков. При старте чанк-сервера мастер запоминает его чанки. В процессе работы мастер контролирует все перемещения чанков и состояния чанк-серверов. Таким образом, он обладает всей информацией о положении каждого чанка.
Важная часть метаданных - это лог операций. Мастер хранит последовательность операций критических изменений метаданных. По этим отметкам в логе операций, определяется логическое время системы. Именно это логическое время определяет версии файлов и чанков.
Так как лог операций важная часть, то он должен надежно храниться, и все изменения в нем должны становиться видимыми для клиентов, только когда изменятся метаданные. Лог операций реплицируется на несколько удаленных машин, и система реагирует на клиентскую операцию, только после сохранения этого лога на диск мастера и диски удаленных машин.
Мастер восстанавливает состояние системы, исполняя лог операций. Лог операций сохраняет относительно небольшой размер, сохраняя только последние операции. В процессе работы мастер создает контрольные точки, когда размер лога превосходит некоторой величины, и восстановить систему можно только до ближайшей контрольной точки. Далее по логу можно заново воспроизвести некоторые операции, таким образом, система может откатываться до точки, которая находится между последней контрольной точкой и текущем временем.

Взаимодействия внутри системы

Выше была описана архитектура системы, которая минимизирует вмешательства мастера в выполнение операций. Теперь же рассмотрим, как взаимодействуют клиент, мастер и чанк-серверы для перемещения данных, выполнения атомарных операций записи, и создания резервной копии (snapshot).
Каждое изменение чанка должно дублироваться на всех репликах и изменять метаданные. В GFS мастер дает чанк во владение (lease) одному из серверов, хранящих этот чанк. Такой сервер называется первичной (primary) репликой. Остальные реплики объявляются вторичными (secondary). Первичная реплика собирает последовательные изменения чанка, и все реплики следуют этой последовательности, когда эти изменения происходят.
Механизм владения чанком устроен таким образом, чтобы минимизировать нагрузку на мастера. При выделении памяти сначала выжидается 60 секунд. А затем, если потребуется первичная реплика может запросить мастера на расширение этого интервала и, как правило, получает положительный ответ. В течение этого выжидаемого периода мастер может отменить изменения.
Рассмотрим подробно процесс записи данных. Он изображен по шагам на рисунке, при этом тонким линиям соответствуют потоки управления, а жирным потоки данных.


Этот рисунок также взят из оригинальной статьи.
  1. Клиент спрашивает мастера, какой из чанк-серверов владеет чанком, и где находится этот чанк в других репликах. Если необходимо, то мастер отдает чанк кому-то во владение.
  2. Мастер в ответ выдает первичную реплику, и остальные (вторичные) реплики. Клиент хранит эти данные для дальнейших действий. Теперь, общение с мастером клиенту может понадобиться только, если первичная реплика станет недоступной.
  3. Далее клиент отсылает данные во все реплики. Он может это делать в произвольном порядке. Каждый чанк-сервер будет их хранить в специальном буфере, пока они не понадобятся или не устареют.
  4. Когда все реплики примут эти данные, клиент посылает запрос на запись первичной реплике. В этом запросе содержатся идентификация данных, которые были посланы в шаге 3. Теперь первичная реплика устанавливает порядок, в котором должны выполняться все изменения, которые она получила, возможно от нескольких клиентов параллельно. И затем, выполняет эти изменения локально в этом определенном порядке.
  5. Первичная реплика пересылает запрос на запись всем вторичным репликам. Каждая вторичная реплика выполняет эти изменения в порядке, определенном первичной репликой.
  6. Вторичные реплики рапортуют об успешном выполнении этих операций.
  7. Первичная реплика шлет ответ клиенту. Любые ошибки, возникшие в какой-либо реплике, также отсылаются клиенту. Если ошибка возникла при записи в первичной реплике, то и запись во вторичные реплики не происходит, иначе запись произошла в первичной реплике, и подмножестве вторичных. В этом случае клиент обрабатывает ошибку и решает, что ему дальше с ней делать.
Из примера выше видно, что создатели разделили поток данных и поток управления. Если поток управления идет только в первичную реплику, то поток данных идет во все реплики. Это сделано, чтобы избежать создания узких мест в сети, а взамен широко использовать пропускную способность каждой машины. Так же, чтобы избежать узких мест и перегруженных связей, используется схема передачи ближайшему соседу по сетевой топологии. Допустим, что клиент передает данные чанк-серверам S1 ,..., S4 . Клиент шлет ближайшему серверу данные, пусть S1 . Он далее пересылает ближайшему серверу, пусть будет S2 . Далее S2 пересылает их ближайшему S3 или S4 , и так далее.
Также задержка минимизируется за счет использования конвейеризации пакетов передаваемых данных по TCP . То есть, как только чанк-сервер получил какую-то часть данных, он немедленно начинает их пересылать. Без сетевых заторов, идеальное время рассылки данных объемом B байт на R реплик будет B/T + RL , где T сетевая пропускная способность, а L - задержка при пересылке одного байта между двумя машинами.
GFS поддерживает такую операцию, как атомарное добавление данных в файл. Обычно, при записи каких-то данных в файл, мы указываем эти данные и смещение. Если несколько клиентов производят подобную операцию, то эти операции нельзя переставлять местами (это может привести к некорректной работе). Если же мы просто хотим дописать данные в файл, то в этом случае мы указываем только сами данные. GFS добавит их атомарной операцией. Вообще говоря, если операция не выполнилась на одной из вторичных реплик, то GFS , вернет ошибку, а данные будут на разных репликах различны.
Еще одна интересная вещь в GFS - это резервные копии (еще можно сказать мгновенный снимок) файла или дерева директорий, которые создаются почти мгновенно, при этом, почти не прерывая выполняющиеся операции в системе. Это получается за счет технологии похожей на сopy on write . Пользователи используют эту возможность для создания веток данных или как промежуточную точку, для начала каких-то экспериментов.

Операции, выполняемые мастером

Мастер важное звено в системе. Он управляет репликациями чанков: принимает решения о размещении, создает новые чанки, а также координирует различную деятельность внутри системы для сохранения чанков полностью реплицированными, балансировки нагрузки на чанк-серверы и сборки неиспользуемых ресурсов.
В отличие от большинства файловых систем GFS не хранит состав файлов в директории. GFS логически представляет пространство имен, как таблицу, которая отображает каждый путь в метаданные. Такая таблица может эффективно храниться в памяти в виде бора (словаря этих самых путей). Каждая вершина в этом дереве (соответствует либо абсолютному пути к файлу, либо к директории) имеет соответствующие данные для блокировки чтения и записи(read write lock). Каждое операция мастера требует установления некоторых блокировок. В этом месте в системе используются блокировки чтения-записи. Обычно, если операция работает с /d1/d2/.../dn/leaf , то она устанавливает блокировки на чтение на /d1, /d1/d2, ..., d1/d2/.../dn и блокировку, либо на чтение, либо на запись на d1/d2/.../dn/leaf . При этом leaf может быть как директорией, так и файлом.
Покажем на примере, как механизм блокировок может предотвратить создание файла /home/user/foo во время резервного копирования /home/user в /save/user . Операция резервного копирования устанавливает блокировки на чтение на /home и /save , а так же блокировки на запись на /home/user и /save/user . Операция создания файла требует блокировки на чтение /home и /home/user , а также блокировки на запись на /home/user/foo . Таким образом, вторая операция не начнет выполняться, пока не закончит выполнение первая, так как есть конфликтующая блокировка на /home/user . При создании файла не требуется блокировка на запись родительской директории, достаточно блокировки на чтение, которая предотвращает удаление этой директории.
Кластеры GFS , являются сильно распределенными и многоуровневыми. Обычно, такой кластер имеет сотни чанк-серверов, расположенных на разных стойках. Эти сервера, вообще говоря, доступны для большого количества клиентов, расположенных в той же или другой стойке. Соединения между двумя машинами из различных стоек может проходить через один или несколько свитчей. Многоуровневое распределение представляет очень сложную задачу надежного, масштабируемого и доступного распространения данных.
Политика расположения реплик старается удовлетворить следующим свойствам: максимизация надежности и доступности данных и максимизация использование сетевой пропускной способности. Реплики должны быть расположены не только на разных дисках или разных машинах, но и более того на разных стойках. Это гарантирует, что чанк доступен, даже если целая стойка повреждена или отключена от сети. При таком расположении чтение занимает время приблизительно равное пропускной способности сети, зато поток данных при записи должен пройти через различные стойки.
Когда мастер создает чанк, он выбирает где разместить реплику. Он исходит из нескольких факторов:
  • Желательно поместить новую реплику на чанк-сервер с наименьшей средней загруженностью дисков. Это будет со временем выравнивать загруженность дисков на различных серверах.
  • Желательно ограничить число новых создаваемых чанков на каждом чанк-сервере. Несмотря на то, что создание чанка сама по себе быстрая операция, она подразумевает последующую запись данных в этот чанк, что уже является тяжелой операцией, и это может привести к разбалансировке объема трафика данных на разные части системы.
  • Как сказано выше, желательно распределить чанки среди разных стоек.
Как только число реплик падает ниже устанавливаемой пользователем величины, мастер снова реплицирует чанк. Это может случиться по нескольким причинам: чанк-сервер стал недоступным, один из дисков вышел из строя или увеличена величина, задающая число реплик. Каждому чанку, который должен реплицироваться, устанавливается приоритет, который тоже зависит от нескольких факторов. Во-первых, приоритет выше у того чанка, который имеет наименьшее число реплик. Во-вторых, чтобы увеличить надежность выполнения приложений, увеличивается приоритет у чанков, которые блокируют прогресс в работе клиента
Мастер выбирает чанк с наибольшим приоритетом и копирует его, отдавая инструкцию одному из чанк-серверов, скопировать его с доступной реплики. Новая реплика располагается, исходя из тех же причин, что и при создании.
Во время работы мастер постоянно балансирует реплики. В зависимости от распределения реплик в системе, он перемещает реплику для выравнивания загруженности дисков и балансировки нагрузки. Также мастер должен решать, какую из реплик стоит удалить. Как правило, удаляется реплика, которая находится на чанк-сервере с наименьшим свободным местом на жестких дисках.
Еще одна важная функция, лежащая на мастере - это сборка мусора. При удалении файла, GFS не требует мгновенного возвращения освободившегося дискового пространства. Он делает это во время регулярной сборки мусора, которая происходит как на уровне чанков, так и на уровне файлов. Авторы считают, что такой подход делает систему более простой и надежной.
При удалении файла приложением, мастер запоминает в логах этот факт, как и многие другие. Тем не менее, вместо требования немедленного восстановления освободившихся ресурсов, файл просто переименовывается, причем в имя файла добавляется время удаления, и он становится невидимым пользователю. А мастер, во время регулярного сканирования пространства имен файловой системы, реально удаляет все такие скрытые файлы, которые были удалены пользователем более трех дней назад (этот интервал настраивается). А до этого момента файл продолжает находиться в системе, как скрытый, и он может быть прочитан или переименован обратно для восстановления. Когда скрытый файл удаляется мастером, то информация о нем удаляется также из метаданных, а все чанки этого файла отцепляются от него.
Мастер помимо регулярного сканирования пространства имен файлов делает аналогичное сканирование пространства имен чанков. Мастер определяет чанки, которые отсоединены от файла, удаляет их из метаданных и во время регулярных связей с чанк-серверами передает им сигнал о возможности удаления всех реплик, содержащих заданный чанк. У такого подхода к сборке мусора много преимуществ, при одном недостатке: если место в системе заканчивается, а отложенное удаление увеличивает неиспользуемое место, до момента самого физического удаления. Зато есть возможность восстановления удаленных данных, возможность гибкой балансировки нагрузки при удалении и возможность восстановления системы, в случае каких-то сбоев.

Устойчивость к сбоям и диагностика ошибок

Авторы системы считают одной из наиболее сложных проблем частые сбои работы компонентов системы. Количество и качество компонентов делают эти сбои не просто исключением, а скорее нормой. Сбой компонента может быть вызван недоступностью этого компонента или, что хуже, наличием испорченных данных. GFS поддерживает систему в рабочем виде при помощи двух простых стратегий: быстрое восстановление и репликации.
Быстрое восстановление - это, фактически, перезагрузка машины. При этом время запуска очень маленькое, что приводит к маленькой заминке, а затем работа продолжается штатно. Про репликации чанков уже говорилось выше. Мастер реплицирует чанк, если одна из реплик стала недоступной, либо повредились данные, содержащие реплику чанка. Поврежденные чанки определяется при помощи вычисления контрольных сумм.
Еще один вид репликаций в системе, про который мало было сказано - это репликация мастера. Реплицируется лог операций и контрольные точки (checkpoints). Каждое изменение файлов в системе происходит только после записи лога операций на диски мастером, и диски машин, на которые лог реплицируется. В случае небольших неполадок мастер может перезагрузиться. В случае проблем с жестким диском или другой жизненно важной инфраструктурой мастера, GFS стартует нового мастера, на одной из машин, куда реплицировались данные мастера. Клиенты обращаются к мастеру по DNS, который может быть переназначен новой машине. Новый мастер является тенью старого, а не точной копией. Поэтому у него есть доступ к файлам только для чтения. То есть он не становится полноценным мастером, а лишь поддерживает лог операций и другие структуры мастера.
Важной частью системы является возможность поддерживать целостность данных. Обычный GFS кластер состоит из сотен машин, на которых расположены тысячи жестких дисков, и эти диски при работе с завидным постоянством выходят из строя, что приводит к порче данных. Система может восстановить данные с помощью репликаций, но для этого необходимо понять испортились ли данные. Простое сравнение различных реплик на разных чанк-серверах является неэффективным. Более того, может происходить несогласованность данных между различными репликами, ведущая к различию данных. Поэтому каждый чанк-сервер должен самостоятельно определять целостность данных.
Каждый чанк разбивается на блоки длиной 64 Кбайт . Каждому такому блоку соответствует 32 -битная контрольная сумма. Как и другие метаданные эти суммы хранятся в памяти, регулярно сохраняются в лог, отдельно от данных пользователя.
Перед тем как считать данные чанк-сервер проверяет контрольные суммы блоков чанка, которые пересекаются с затребованными данными пользователем или другим чанк-сервером. То есть чанк-сервер не распространяет испорченные данные. В случае несовпадения контрольных сумм, чанк-сервер возвращает ошибку машине, подавшей запрос, и рапортует о ней мастеру. Пользователь может считать данные из другой реплики, а мастер создает еще одну копию из данных другой реплики. После этого мастер дает инструкцию этому чанк-серверу об удалении этой испорченной реплики.
При добавлении новых данных, верификация контрольных сумм не происходит, а для блоков записывается новые контрольные суммы. В случае если диск испорчен, то это определится при попытке чтения этих данных. При записи чанк-сервер сравнивает только первый и последний блоки, пересекающиеся с границами, в которые происходит запись, поскольку часть данных на этих блоках не перезаписывается и необходимо проверить их целостность.