Лекция: Файловая система AFS
Файловая система AFS была разработана и реализована в университете Карнеги-Меллона. Эта система была названа Andrew File System в честь двух первых спонсоров университета Эндрю Карнеги и Эндрю Меллона. Цель проекта, запущенного в начале 80-х годов, заключалась в обеспечении каждого студента и каждого сотрудника университета мощной рабочей станцией под управлением операционной системы UNIX, но с общей файловой системой. В данном случае файловая система использовалась в качестве системы промежуточного программного обеспечения, чтобы превратить множество рабочих станций в единую когерентную систему.
Рис. 157
У каждого пользователя файловой системы AFS есть своя рабочая станция, на которой работает слегка модифицированная версия системы UNIX. Модификация заключается в добавлении к ядру программы, называемой venus (Венера), и запуске файлового сервера vice (вице-сервера) в пространстве пользователя. (Изначально программа venus также работала в пользовательском пространстве, но затем она была перемещена в ядро по соображениям производительности). Расположение программ venus и vice показано на рис. 157, а. В административных целях рабочие станции пользователей группируются в ячейки. Ячейкой может быть локальная сеть, множество объединенных локальных сетей или даже целый факультет.
Видимое программам пользователя пространство имен выглядит как традиционное дерево UNIX с добавлением каталогов /cmu и /cache (рис. 157, б). Каталог /cache содержит имена кэшированных удаленных файлов. Каталог /cmu содержит имена удаленных совместно используемых ячеек, под которыми располагаются их файловые системы. В результате удаленные файловые системы монтируются в каталоге /cmu. Остальные каталоги и файлы являются локальными и не используются совместно. Разрешаются символьные ссылки от локальных файлов к совместно используемым файлам, как показано на примере файла sh на рис. 157, б.
Основная идея файловой системы AFS заключается в том, чтобы пользователь максимально применял потенциал локальной работы и, по возможности, минимально взаимодействовал с остальной частью системы. При открытии файла программа venus перехватывает системный вызов open и загружает файл целиком (или если файл очень велик, то большую его часть) на локальный диск в каталог /cache. Дескриптор файла, возвращаемый системным вызовом open, ссылается на файл в каталоге /cache, так что последующие системные вызовы read и write используют этот кэшированный файл.
Семантика, предлагаемая файловой системой AFS, близка к сеансовой семантике. Когда файл открывается, он получается с соответствующего сервера и помещается в каталог /cache на локальном диске рабочей станции. Все операции чтения и записи выполняются с этой кэшированной копией файла. Когда файл закрывается, он закачивается обратно на сервер.
Однако для предотвращения возможности использования старых копий файла другими процессами программа venus, загружая файл в кэш, сообщает программе vice, следует ли отслеживать последовательные обращения других процессов к этому файлу. Если да, то вице-сервер записывает расположение кэшированного файла. Когда другой процесс системы открывает этот же файл, программа vice посылает программе venus соответствующее сообщение, после чего программа venus помечает элемент кэша как недействительный и, если копия файла была изменена, она копируется обратно на сервер.
Рис. 158
Технология CORBA представляет собой систему типа клиент-сервер, в которой клиентский процесс может осуществлять операции с объектами, расположенными на серверах. Архитектура CORBA была разработана для неоднородной системы, состоящей из разнообразных аппаратных платформ и операционных систем, и программировалась на нескольких языках. Чтобы клиент на одной платформе мог вызвать сервер на другой платформе, между клиентом и сервером располагаются специальные программные посредники, называемые ORB (Object Request Broker – брокер объектных запросов). Посредники ORB играют в архитектуре CORBA важную роль. Благодаря им сама архитектура получила свое название.
Каждый объект системы CORBA описывается на специальном языке описания интерфейсов IDL (Interface Definition Language). В определении объекта указываются методы, экспортируемые объектом, и типы параметров для каждого метода. Спецификация IDL может быть откомпилирована в клиентскую процедуру-заглушку и храниться в библиотеке. Если клиентскому процессу заранее известно, что ему потребуется доступ к определенному объекту, этот объект компонуется вместе с объектным кодом клиентской заглушки. Спецификация IDL также может быть откомпилирована вместе со скелетной процедурой, используемой на серверной стороне. Если заранее нельзя сказать, какие объекты CORBA понадобятся процессу, возможно также применение динамического вызова, но принципы работы этого метода выходят за пределы данной книги.
При создании объекта CORBA также создается ссылка на этот объект, которая возвращается процессу, создавшему объект. В дальнейшем процесс обращается к методам созданного объекта по этой ссылке. Ссылка может быть передана другим процессам или сохранена в объектной библиотеке.
Чтобы вызвать метод объекта, клиентский процесс сначала должен получить ссылку на этот объект. Ссылку можно получить либо напрямую от создавшего объект процесса, либо при помощи поиска этого объекта или его метода по имени в специальном каталоге. Когда ссылка на объект получена, клиентский процесс упаковывает параметры вызываемого метода в стандартную структуру и связывается с клиентским ORB-посредником. Тот, в свою очередь, посылает сообщение серверному ORB-посреднику, который вызывает метод объекта. Весь механизм схож с вызовом удаленной процедуры RPC.
Цель ORB-посредников заключается в сокрытии всех низкоуровневых деталей связи и распределения от клиентской и серверной программ. В частности, ORB-посредники скрывают от клиента расположение сервера, аппаратное обеспечение сервера и операционную систему, работающую на сервере, информацию о том, является ли сервер двоичной программой или сценарием, является ли объект активным в настоящий момент, а также способ общения двух ORB-посредников (TCP/IP, RPC, общая память и т. д.).
В первой версии системы CORBA протокол между клиентским и серверным ORB-посредниками не был определен. В результате каждый разработчик ORB-посредников использовал свой отличный протокол, и различные реализации ORB не могли общаться друг с другом. Протокол был определен в версии 2.0. Для связи через Интернет используется протокол, называемый IIOP (Internet InterORB Protocol – протокол для связи между ORB-посредниками по Интернету).
Чтобы было можно использовать в системах CORBA объекты, не предназначенные специально для этого, каждый объект оснащается адаптером объекта. Это упаковщик, обрабатывающий такие рутинные операции, как формирование ссылок на объект и активация объекта в случае, если при вызове тот находится в неактивном состоянии.
Серьезный недостаток системы CORBA заключается в том, что каждый объект расположен только на одном сервере, что означает крайне низкую производительность для объектов, одновременно используемых многими клиентами. На практике архитектура CORBA может приемлемо работать только в небольших системах, например, соединять процессы на одном компьютере, в пределах одной локальной сети или одной компании.
Рис. 159
В качестве примера распределенной объектной системы, специально разработанной для поддержки миллиарда пользователей и триллиона объектов по всему миру, рассмотрим систему Globe. Для создания очень больших систем используются две ключевые идеи. Первая из них – реплицируемые объекты. Если имеется единственная копия популярного объекта, доступ к которому хотят получить миллионы пользователей по всему миру, объект физически не сможет обработать все запросы. Подумайте об объекте, занимающемся биржевыми сводками или результатами спортивных соревнований. Репликация объекта позволяет распределить нагрузку по репликам.
Вторая ключевая идея заключается в гибкости. Во всемирной системе с миллиардом пользователей нет способа добиться всеобщего согласия по вопросу о выборе языка программирования, единой репликационной стратегии, общей модели безопасности или еще по какому-либо вопросу. Система должна позволять различное поведение различных пользователей и различных объектов и в то же самое время обеспечивать когерентную общую модель. Именно это и делает система Globe.
Необычность системы Globe заключается также в том, что, подобно технологии DSM, она основывается на модели распределенной совместно используемой памяти, но применительно ко всемирному контексту. В принципе использование нормальной технологии DSM, основанной на страницах, будет работать и в мировых масштабах, но вот производительность такой системы будет очень низкой, поэтому в системе Globe применяется другой подход. Концептуально основная идея состоит в том, что мир полон объектов, каждый из которых содержит некое (скрытое) состояние и методы, обеспечивающие управляемый доступ к этому состоянию. Чтобы создать совместно используемую память в мировом масштабе, нужно запретить прямой доступ к внутреннему состоянию объекта при помощи команд LOAD и STORE и разрешить весь доступ только через методы. Так как объект системы Globe может одновременно активно использоваться многими процессами, он также называется распределенным совместно используемым объектом.
Рассмотрим теперь реализацию масштабируемости и гибкости. У каждого объекта системы Globe есть объект класса, содержащий программы его методов. У каждого объекта также есть интерфейс или несколько интерфейсов, каждый из которых содержит пары (указатель на метод, указатель на состояние). Таким образом, имея интерфейс объекта, представляющий собой таблицу указателей, находящуюся в памяти во время исполнения, процесс может вызвать n-й метод, обратившись к процедуре, на которую указывает n-я пара в таблице интерфейса, и передав ей соответствующий указатель на состояние в качестве параметра. Указатель на состояние нужен на тот случай, если в памяти одновременно присутствуют, например, два объекта класса mailbox (почтовый ящик). У каждого объекта при этом есть собственный интерфейс и указатели состояния, но у обоих объектов общие указатели методов. В данном примере у процесса есть два открытых почтовых ящика, совместно использующих четыре метода, но каждый со своим собственным состоянием (сообщениями, сохраняемыми в экземпляре почтового ящика). Например, один почтовый ящик может быть для деловой переписки, а другой – для личной корреспонденции.
Хранение интерфейсов во время исполнения в таблицах в памяти означает, что объекты не ограничены использованием какого-либо одного языка. Такое решение было выбрано, так как во всемирной системе будет множество различных пользователей и программистов со своими языковыми предпочтениями. Методы объектов могут быть написаны на С, C++, Java или даже на ассемблере, если так пожелает владелец объекта. Цель интерфейсов состоит в том, чтобы скрывать от процессов то, что располагается за указателями методов. Такой комбинированный метод является более гибким, чем использование только одного языка, применяющийся в некоторых системах.
Чтобы использовать объект Globe, процесс должен сначала связаться с ним, для чего этот объект нужно найти и определить хотя бы один адрес контакта (например, IP-адрес и порт). Проверка безопасности производится во время связывания, и если процессу разрешено связывать этот объект, объект класса (то есть программа) загружается в адресное пространство процесса, создается экземпляр класса, и процессу возвращается указатель на его (стандартный) интерфейс. При помощи указателя на интерфейс процесс может вызывать методы, оперируя данным экземпляром объекта. В зависимости от объекта его состояние может быть состоянием по умолчанию или копией его текущего состояния, взятого у одной из уже существующих копий.
Рис. 160
Представим себе простейший объект. У этого объекта есть целое число в качестве состояния и два метода: read (чтение) и write (запись), оперирующие с этим целым числом. Если несколько процессов в разных странах одновременно связываются с этим объектом, у всех них будет интерфейсная таблица, указывающая на объект класса, содержащий два метода (загружаемая во время связывания). У каждого процесса (потенциально) также есть копия целого числа, содержащего состояние объекта. Каждый метод read реализуется локально, но вызов метода write более сложен. Если объект хочет поддерживать последовательную непротиворечивость, для этого требуется специальный механизм.
Один из вариантов такого механизма заключается в наличии процесса, называемого задатчиком последовательности, чья работа состоит в выдаче последовательных номеров при обращении к нему. Чтобы выполнить операцию записи, метод write сначала получает последовательный номер, после чего при помощи многоадресной рассылки распространяет сообщение, содержащее этот порядковый номер, имя операции и параметр всем остальным процессам, связанным с этим объектом. Если два процесса одновременно вызовут метод write, они получат разные порядковые номера. Все процессы должны выполнять входящие методы в порядке номеров, а не в порядке их получения.
Приведенная выше схема репликации с равными копиями реплицированного объекта и разрешением обновления только после получения порядкового номера представляет собой лишь один из многих вариантов репликационных протоколов. В другом варианте хранится одна эталонная (главная) копия для каждого объекта плюс несколько подчиненных копий. Все обновления посылаются эталону, который выполняет обновление и рассылает новое состояние всем подчиненным копиям.
Третья стратегия репликации объекта заключается в том, что состояние может быть только у одной копии объекта, тогда как все остальные копии являются заместителями объекта, не имеющими собственного состояния. Когда такой заместитель (например, клиентская машина) получает запрос метода read или write, он переадресовывает этот запрос копии, хранящей состояние, и запрос выполняется там.
Управляющий объект принимает вызовы методов и использует другие подобъекты для их выполнения. Семантический подобъект выполняет работу, требуемую интерфейсом объекта. Программист, создающий объект, должен написать только часть программы объекта. Все остальное берется из стандартных библиотек, если только программист не хочет реализовать новую, еще не доступную стратегию. Репликационный подобъект занимается репликацией. Этот модуль может быть заменен, если вместо активной репликации желательно использовать репликацию типа «главный-подчиненный» или какую-либо другую репликационную стратегию, не затрагивая при этом остальной объект. Подобным же образом для реализации новой стратегии безопасности можно заменить подобъект безопасности, а для смены протокола можно заменить подобъект связи, и это не повлияет на остальные объекты.
Когда вызывается один из методов объекта, программа, на которую указывает интерфейс, представляет собой управляющий подобъект, который просит подобъект репликации выполнить необходимые действия. Если объект реплицируется активно, сначала получается порядковый номер. Затем подобъект репликации велит всем репликам (включая собственную) выполнить работу, вызывая их семантические объекты. Если тип объекта «главный-подчиненный», а вызываемый метод находится на подчиненном объекте, то главному объекту посылается сообщение и т. д. В определенные моменты объект безопасности выполняет проверку (разрешен ли вызов метода, должны ли быть зашифрованы исходящие данные и т. д.).
Рис. 161
Ключевым элементом системы Globe является служба обнаружения, позволяющая находить объект, где бы тот ни находился. Служба обнаружения строится в виде дерева, в узлах которого хранятся регистрационные данные объектов. Указатели на эти узлы передаются вверх по дереву, поэтому всегда можно найти сведения об объекте. Чтобы такая схема могла работать даже с мобильными объектами, используются различные методы, включая группирование узлов дерева, кэширование и т. д.
Публикация / подписка
Эта модель состоит из нескольких процессов, соединенных широковещательной сетью. Каждый процесс может производить информацию, потреблять информацию или и то и другое.
Когда у производителя информации есть новая информация (например, новые биржевые сводки), он рассылает ее всем по сети в виде кортежа. Это действие называется публикацией. Каждый кортеж содержит иерархически структурированную строку темы публикации с полями, разделенными точками. Процессы, которых интересуют определенные темы, могут подписаться на них. При этом можно использовать символ звездочки для обозначения всех разделов какой-либо темы. Чтобы подписаться на какую-либо тему, нужно сообщить ее специальному демону кортежей, работающему на той же машине, что и процесс.
Рис. 162
Реализация модели «публикация/подписка» показана на рис. 162. Когда у процесса есть кортеж для публикации, он рассылает его с помощью широковещания по локальной сети. Демон кортежей на каждой машине копирует все рассылаемые подобным образом кортежи в ОЗУ. Затем он просматривает строку темы сообщения, чтобы определить, которые процессы заинтересованы в получении этой информации, пересылая каждому такому процессу копию полученного сообщения. Кортежи также могут рассылаться по глобальным сетям или по Интернету. Для этого в каждой локальной сети одна машина должна исполнять роль информационного маршрутизатора, собирая все опубликованные кортежи и пересылая их другим локальным сетям, реализуя, таким образом, широковещание. При этом можно учитывать наличие в локальной сети-получателе хотя бы одного заинтересованного подписчика, дабы не занимать зря линии передачи. Для этого информационные маршрутизаторы должны обмениваться информацией о подписчиках.
В данной модели могут быть реализованы различные типы семантики, включая надежную доставку и гарантированную доставку, даже в случае сбоев компьютеров. В последнем случае необходимо хранить старые кортежи на случай, если они понадобятся впоследствии. Они могут храниться в базе данных, которая подписывается на все темы кортежей. Это может быть выполнено при помощи упаковывания базы данных в адаптер, чтобы имеющаяся база данных могла работать в модели «публикация/подписка». По мере поступления кортежи перехватываются адаптером и помещаются в базу данных.
Контрольные вопросы