В этом посте собраны материалы, представленные в статье Примечание о распределенных системах, опубликованной в 1994 году Джимом Уолдо и другими.

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

Вступление

Документ начинается с утверждения, что текущая работа в распределенных системах моделируется вокруг объектов - точнее, унифицированного представления объектов. Объекты определяются их поддерживаемыми интерфейсами и поддерживаемыми ими операциями.

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

Давайте определим наиболее общие термины в этой статье:

Локальные вычисления

Он имеет дело с программами, которые ограничены только одним адресным пространством.

Распределенных вычислений

Он имеет дело с программами, которые могут обращаться к объектам в разных адресных пространствах либо на одном компьютере, либо на другом компьютере.

Видение единых объектов

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

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

Что касается программистов, они пишут один и тот же тип вызова для каждого объекта, будь то локальный или удаленный. Система заботится об отправке сообщения, выясняя основные механизмы, не видимые программисту, который пишет приложение.

Сложные проблемы распределенных вычислений - это не проблемы, как включить или выключить сеть.

Далее в статье определяются самые сложные задачи построения распределенной системы:

  1. Задержка
  2. Доступ к памяти
  3. Частичный сбой и параллелизм

Обеспечение разумной производительности при работе со всем вышеперечисленным не облегчает жизнь инженера по распределенным системам. А отсутствие какого-либо центрального ресурса или государственного менеджера усугубляет различные проблемы. Давайте рассмотрим каждый из них по очереди.

Задержка

Это фундаментальное различие между вызовом локального и распределенного объекта.

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

Вам необходимо хорошо понимать разрабатываемое приложение, чтобы вы могли решить, какие объекты следует хранить вместе, а какие можно разместить удаленно.

Если цель состоит в том, чтобы объединить разницу в задержке, у нас есть два варианта:

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

объем памяти

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

У нас осталось два варианта:

  • Разработчик должен осознавать разницу между шаблонами доступа.
  • Чтобы унифицировать различия в доступе между локальным и удаленным доступом, нам нужно позволить системе обрабатывать все аспекты доступа к памяти.

Есть несколько способов сделать это:

  • Распределенная разделяемая память
  • Используя парадигму ООП (объектно-ориентированное программирование), составьте систему, полностью состоящую из объектов - такую, которая имеет дело только со ссылками на объекты.
    Можно решить проблему передачи данных между адресными пространствами. путем маршалинга и демаршалинга данных нижележащим слоем. Однако этот подход делает использование указателей относительно адресного пространства устаревшим.

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

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

Частичный сбой и параллелизм

Частичный отказ - основная реальность распределенных вычислений.

В документе утверждается, что как локальные, так и распределенные системы подвержены сбоям. Но сложнее обнаружить, что пошло не так в случае распределенных систем.

В локальной системе либо все выключено, либо есть какой-то центральный орган, который может обнаружить, что пошло не так (например, ОС).

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

Центральная проблема в распределенных вычислениях - обеспечение того, чтобы состояние всей системы оставалось неизменным после такого сбоя. Это проблема, которая просто не возникает при локальных вычислениях.

Чтобы система выдерживала частичный отказ, важно, чтобы она имела дело с неопределенностью и чтобы объекты реагировали на нее согласованным образом. По возможности интерфейсы должны иметь возможность указывать причину сбоя. А затем разрешить реконструкцию «разумного состояния» в случае, если причина не может быть определена.

Вопрос не в том, «можете ли вы сделать вызов удаленного метода похожим на вызов локального метода», а скорее в том, «какова цена совершения вызова удаленного метода, идентичного вызову локального метода?»

На ум приходят два подхода:

  1. Считайте все интерфейсы и объекты локальными. Проблема этого подхода в том, что он не принимает во внимание модели отказов, связанные с распределенными системами. Следовательно, он по своей природе недетерминирован.
  2. Считайте все интерфейсы и объекты удаленными. Недостаток этого подхода в том, что он чрезмерно усложняет локальные вычисления. Это добавляет массу работы для объектов, к которым никогда не удается получить удаленный доступ.

Лучший подход - признать наличие непримиримых различий между локальными и распределенными вычислениями и осознавать эти различия на всех этапах проектирования и реализации распределенных приложений.

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