В этом посте собраны материалы, представленные в статье Примечание о распределенных системах, опубликованной в 1994 году Джимом Уолдо и другими.
В статье представлены различия между локальными и распределенными вычислениями в контексте объектно-ориентированного программирования. Это объясняет, почему относиться к ним так же неправильно и приводит к тому, что приложения не являются надежными и ненадежными.
Вступление
Документ начинается с утверждения, что текущая работа в распределенных системах моделируется вокруг объектов - точнее, унифицированного представления объектов. Объекты определяются их поддерживаемыми интерфейсами и поддерживаемыми ими операциями.
Естественно, это может быть расширено, чтобы подразумевать, что объекты в одном и том же адресном пространстве или в другом адресном пространстве на одной или другой машине ведут себя одинаково. Их расположение - деталь реализации.
Давайте определим наиболее общие термины в этой статье:
Локальные вычисления
Он имеет дело с программами, которые ограничены только одним адресным пространством.
Распределенных вычислений
Он имеет дело с программами, которые могут обращаться к объектам в разных адресных пространствах либо на одном компьютере, либо на другом компьютере.
Видение единых объектов
В этом видении подразумевается, что система будет «полностью вниз объектами». Это означает, что все текущие вызовы или вызовы системных служб в конечном итоге будут преобразованы в вызовы, которые могут быть сделаны к объекту, находящемуся на какой-либо другой машине. Существует единая парадигма использования объекта и коммуникации, независимо от того, в каком месте находится объект.
Это относится к предположению, что все объекты определены только в терминах их интерфейсов. Их реализация также включает в себя расположение объекта, не зависит от их интерфейсов и скрыта от программиста.
Что касается программистов, они пишут один и тот же тип вызова для каждого объекта, будь то локальный или удаленный. Система заботится об отправке сообщения, выясняя основные механизмы, не видимые программисту, который пишет приложение.
Сложные проблемы распределенных вычислений - это не проблемы, как включить или выключить сеть.
Далее в статье определяются самые сложные задачи построения распределенной системы:
- Задержка
- Доступ к памяти
- Частичный сбой и параллелизм
Обеспечение разумной производительности при работе со всем вышеперечисленным не облегчает жизнь инженера по распределенным системам. А отсутствие какого-либо центрального ресурса или государственного менеджера усугубляет различные проблемы. Давайте рассмотрим каждый из них по очереди.
Задержка
Это фундаментальное различие между вызовом локального и распределенного объекта.
В документе утверждается, что удаленный вызов в четыре-пять раз медленнее, чем местный. Если конструкция системы не учитывает это фундаментальное различие, она неизбежно страдает от серьезных проблем с производительностью. Особенно, если он полагается на удаленное общение.
Вам необходимо хорошо понимать разрабатываемое приложение, чтобы вы могли решить, какие объекты следует хранить вместе, а какие можно разместить удаленно.
Если цель состоит в том, чтобы объединить разницу в задержке, у нас есть два варианта:
- Положитесь на оборудование, чтобы со временем работать быстрее и устранить разницу в эффективности
- Разработайте инструменты, которые позволят нам визуализировать модели взаимодействия между различными объектами и перемещать их по мере необходимости. Поскольку местоположение является деталью реализации, этого не должно быть слишком сложно.
объем памяти
Еще одно отличие, которое очень важно для проектирования распределенных систем, - это модель доступа к памяти между локальными и удаленными объектами. Указатель в локальном адресном пространстве недействителен в удаленном адресном пространстве.
У нас осталось два варианта:
- Разработчик должен осознавать разницу между шаблонами доступа.
- Чтобы унифицировать различия в доступе между локальным и удаленным доступом, нам нужно позволить системе обрабатывать все аспекты доступа к памяти.
Есть несколько способов сделать это:
- Распределенная разделяемая память
- Используя парадигму ООП (объектно-ориентированное программирование), составьте систему, полностью состоящую из объектов - такую, которая имеет дело только со ссылками на объекты.
Можно решить проблему передачи данных между адресными пространствами. путем маршалинга и демаршалинга данных нижележащим слоем. Однако этот подход делает использование указателей относительно адресного пространства устаревшим.
Опасность заключается в распространении мифа о том, что «удаленный доступ и локальный доступ - это одно и то же». Мы не должны укреплять этот миф. Базовый механизм, который не объединяет все обращения к памяти, но при этом способствует распространению этого мифа, вводит в заблуждение и подвержен ошибкам.
Для программистов важно знать о различных различиях между доступом к локальным и удаленным объектам. Мы не хотим, чтобы их укусило то, что они не знают, что происходит под одеялом.
Частичный сбой и параллелизм
Частичный отказ - основная реальность распределенных вычислений.
В документе утверждается, что как локальные, так и распределенные системы подвержены сбоям. Но сложнее обнаружить, что пошло не так в случае распределенных систем.
В локальной системе либо все выключено, либо есть какой-то центральный орган, который может обнаружить, что пошло не так (например, ОС).
Тем не менее, в случае распределенной системы нет глобального диспетчера состояний или ресурсов, который мог бы отслеживать все, что происходит в системе и в ней. Таким образом, нет никакого способа сообщить другим компонентам, которые могут работать правильно, какие из них вышли из строя. Компоненты распределенной системы выходят из строя независимо.
Центральная проблема в распределенных вычислениях - обеспечение того, чтобы состояние всей системы оставалось неизменным после такого сбоя. Это проблема, которая просто не возникает при локальных вычислениях.
Чтобы система выдерживала частичный отказ, важно, чтобы она имела дело с неопределенностью и чтобы объекты реагировали на нее согласованным образом. По возможности интерфейсы должны иметь возможность указывать причину сбоя. А затем разрешить реконструкцию «разумного состояния» в случае, если причина не может быть определена.
Вопрос не в том, «можете ли вы сделать вызов удаленного метода похожим на вызов локального метода», а скорее в том, «какова цена совершения вызова удаленного метода, идентичного вызову локального метода?»
На ум приходят два подхода:
- Считайте все интерфейсы и объекты локальными. Проблема этого подхода в том, что он не принимает во внимание модели отказов, связанные с распределенными системами. Следовательно, он по своей природе недетерминирован.
- Считайте все интерфейсы и объекты удаленными. Недостаток этого подхода в том, что он чрезмерно усложняет локальные вычисления. Это добавляет массу работы для объектов, к которым никогда не удается получить удаленный доступ.
Лучший подход - признать наличие непримиримых различий между локальными и распределенными вычислениями и осознавать эти различия на всех этапах проектирования и реализации распределенных приложений.
P.S. - Если вы зашли так далеко и хотели бы получать письмо всякий раз, когда я публикую один из этих постов, зарегистрируйтесь здесь.