Давайте начнем с мыслительного упражнения: представьте, что ваше приложение выполняет вызов 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 г.