Давайте начнем с мыслительного упражнения: представьте, что ваше приложение выполняет вызов write(), за которым следует вызов read(). Что вы ожидаете получить обратно в операции чтения? Вот ваши варианты:

  • Всегда получайте последнее обновление
  • Вернуть либо последнее обновление, либо предыдущее значение, но никогда не частичные обновления.
  • Всегда возвращайте последнее обновление, если чтение выполняется из того же сеанса.
  • Как только последнее значение будет возвращено при чтении, последующие чтения никогда не вернут старое устаревшее значение, т. е. монотонная гарантия.
  • Ограниченное устаревание, т. Е. При чтении, выполненном после заданного интервала, всегда будут отображаться последние обновления.
  • И так далее…

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

POSIX можно считать наиболее известным де-факто контрактом между разработчиками приложений и платформой. Стандарт существует уже четыре десятилетия и изначально был изобретен для обеспечения взаимодействия между системами *nix. Хотя POSIX является довольно широким стандартом, определяющим как синтаксис, так и семантику контакта, основное внимание в этом блоге уделяется семантике POSIX, связанной с вводом-выводом.

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

  • Строгая последовательность в отслеживании атрибутов метаданных файла, таких как время доступа, размер и т. д.
  • Обход всей иерархии пространства имен (т. е. каталогов)
  • Гарантия взаимного исключения операций чтения-записи
  • Гарантия строгой сериализуемости одновременных обновлений

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

Подводя итог, можно сказать, что мир POSIX задумывался как универсальный. Эра больших данных, напротив, имеет дело со значительными различиями в объеме, скорости и разнообразии данных. Таким образом, приложения должны искать компромисс между требованиями контракта на хранение в пользу лучшей производительности, масштабируемости и доступности. Было множество блогов, в которых освещались недостатки POSIX в отношении меняющегося ландшафта приложений и архитектур хранения. В прошлом были безуспешные попытки (особенно в сообществе высокопроизводительных вычислений) пересмотреть основные преимущества POSIX IO и предложить новые расширения POSIX.

Цель этого поста не только в том, чтобы подчеркнуть, что POSIX — это не серебряная пуля (надеюсь, теперь это ясно!). У нас все еще остается без ответа вопрос: как мы можем создать интероперабельный семантический контракт для приложений больших данных, чтобы они беспрепятственно работали на разных платформах, а также в частных и общедоступных облачных средах? Сегодня большинство приложений для работы с большими данными (таких как Hadoop, Cassandra, MongoDB и т. д.) обеспечивают совместимость за счет объединения масштабируемого уровня хранения, работающего на локальных дисках/файловых системах. Разрастание одноразовых пакетов не является устойчивым в долгосрочной перспективе. обслуживание и развертывание, и нам нужна единая платформа, которая вместо этого может поддерживать широкий спектр семантических контрактов.

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

Чтобы проиллюстрировать концепцию семантики диапазонов, рассмотрим пример сериализации чтения-записи, представленный в начале этого блога. Лесли Лэмпорт определил классическую таксономию для моделей когерентности без ожидания. Таксономия определила три семантические модели:

  • Безопасные регистры: чтение, перекрывающее запись, может возвращать произвольное значение, т. е. неатомарное значение.
  • Обычные регистры: чтение, перекрывающее запись, может либо вернуть старое значение, либо новое значение.
  • Атомарные регистры: монотонная гарантия того, что если чтение возвращает новое значение, последующее чтение не может вернуть более старое значение.

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

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

  • Схема пространства имен: определяет правила, связанные с именованием объектов, а также связанную с ними иерархию.
  • Адресируемость объекта: определяет семантику для обращения к обновлению внутри объекта. В текущей модели POSIX адресация представляет собой единый плоский поток байтов, где адресация представляет собой кортеж объекта и адреса смещения. Напротив, вектор байтов или модель на основе записей более интуитивно понятны для приложений больших данных.
  • Атомарность обновления. Гарантирует, что результат обновления объекта либо виден полностью, либо не виден вообще. Это измерение также определяет степень детализации атомарности, которая может быть на уровне секторов, блоков, объектов и т. д.
  • Гранулярность упорядочения: определяет степень детализации, с которой система хранения будет сериализовать операции чтения и записи. POSIX на самом деле не определяет семантику упорядочения. Есть интересные таксономические предложения для упорядочения операций ввода-вывода для каждого объекта, каждой реплики или всего пространства имен.
  • Сериализация чтения-записи.Определение поведения при одновременном выполнении операций чтения и записи для одной и той же записи. Об этом было сказано ранее в блоге.
  • Сериализация записи-записи: определяет, как обрабатываются параллельные операции записи-записи. Сегодня POSIX определяет семантику взаимного исключения. Облегченными альтернативами являются семантика Last Writer Wins или обновления версий.
  • Разделение упорядочения и долговечности: это было предложенное расширение POSIX, где приложение уведомляется, когда обновление буферизуется, а затем отдельно, когда данные фактически сохраняются на долговременном носителе.
  • Консистентность метаданных. Позволяет явно вызывать согласованность системных метаданных (таких как размер, время доступа), связанных с объектами данных. POSIX обеспечивает строгую согласованность метаданных
  • Транзакции. Определяет, поддерживает ли система хранения семантику, подобную ACID, для нескольких объектов хранения. Транзакции могут быть дополнительно специализированы на транзакции только для чтения и т. д.

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

Первоначально опубликовано 22 февраля 2015 г.