РЕГИСТРАЦИЯ |
EMAIL
ПАРОЛЬ

 

Выше мы декларировали неограниченную масштабируемость единого пространства объектов. Каким образом можно достичь того, что расширение этого пространства не будет приводить к его постепенной деградации?

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

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

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

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

Программный интерфейс всех сервисов состоит из двух частей: межсервисной и клиентской. Межсервисная часть позволяет формировать иерархию сервисов и реализовывать взаимодействие между сервисами, тогда как в клиентской части механика организации сервисов полностью скрыта. С точки зрения клиента, каждый сервис предоставляет доступ ко всему пространству объектов без каких-либо ограничений - достаточно подключиться к одному произвольному сервису, чтобы получить доступ к любому опубликованному объекту. Как же достигается одновременно доступность любых объектов пространства и отсутствие единственного узла, пропускающего через себя весь поток информации?

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

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

С одной стороны поиск объекта через такие реестры действительно может быть выполнен более-менее эффективно - достаточно подняться по дереву сервисов до того сервиса, реестр которого содержит информацию о месте расположения искомого объекта (подобно алгоритму поиска адреса для домена в DNS). В результате, корневой сервис будет задействован лишь в тех случаях, когда искомые объекты и клиент располагаются в "противоположных" частях пространства объектов.

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

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

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

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

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

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

Здесь встает вопрос - как наиболее рационально организовать иерархию идентификаторов, чтобы минимизировать трудозатраты на ее построение и одновременно обеспечить стабильность идентификатора при перемещении объекта? При ответе на данный вопрос мы используем одно очевидное наблюдение - объекты и свойства объектов образуют иерархию часть целое. Например, объект типа "человек" может иметь свойство "паспорт", которое в свою очередь также является объектом и имеет собственной свойство "номер паспорта". Таким образом, объект может рассматриваться как узел, родительский для всех его свойств. Причем каждое свойство в такой интерпретации также является объектом, а, следовательно, может быть родительским для других свойств. И так далее.

Если мы построим такую иерархию объектов от одного коневого объекта, то иерархический идентификатор произвольного объекта может быть сформирован как путь от корневого объекта к данному. Как при этом идентифицировать каждое звено этого пути? Если мы говорим об объектах и их свойствах, то естественным образом можно использовать имя свойства, так как общеизвестно, что в рамках объекта свойства имеют уникальные имена, а, следовательно, они однозначно идентифицируют каждую ветку дерева. Таким образом, уникальный идентификатор объекта "номер паспорта" может представлять собой /People/Vladimir/Passport/Number, где People - это свойство корневого объекта, Vladimir - свойство объекта People, и так далее.

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

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

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

Также немаловажным следствием является то, что иерархия объектов становится доступной для решения исследовательских задач, а не только для получения конкретного объекта по известному идентификатору. Так пользователь может двигаться по дереву объектов, изучая какие из них существуют и какими свойствами обладают. Более того, на основе данной иерархии может быть построен язык запросов, аналогичный X-Path/X-Query. Эффективное исполнение запросов такого языка - это отдельная тема, естественно, необходима поправка на глобальность пространства объектов.

Далее: Типизация объектов
Назад: Введение