
6.6. Примеры 393
лась система Огса, имеет такие средства. Каждое сообщение, предназначенное
для распространения путем широковещательной рассылки, отправляется специ-
альному процессу под названием
секвенсор
(sequencer),
который присваивает ему
последовательный номер, а затем рассылает его, используя ненадежную аппарат-
ную широковещательную рассылку. Когда процесс обнаруживает пропуск в по-
следовательных номерах, он понимает, что потерял сообщение, и предпринимает
действия по его восстановлению.
Если система не поддерживает надежной широковещательной рассылки (или
не имеет вообще никаких средств рассылки), обновления вносятся при помощи
протокола на базе первичной копии. Каждый объект имеет первичную копию.
Процесс, выполняющий обновление, посылает сначала сообщение первичной
копии объекта, блокирует ее и изменяет. Затем первичная копия посылает инди-
видуальные сообщения всем остальным машинам, имеющим копии этого объек-
та, требуя блокировки этих копий. Когда все они подтвердят наличие блокиров-
ки,
начавший все это процесс переходит во вторую фазу и посылает другое
сообщение, предназначенное для того, чтобы провести операцию и разблокиро-
вать объект.
Взаимные блокировки при этом невозможны. Если два процесса одновремен-
но захотят изменить один и тот же объект, один из них первым заблокирует пер-
вичную копию, а второй будет дожидаться, пока объект снова не освободится.
Кроме того, отметим, что в ходе процесса обновления все копии объекта блоки-
руются, так что ни один из прочих процессов не может считать прежние значе-
ния. Эта блокировка гарантирует, что все операции будут выполняться в гло-
бально уникальном последовательном порядке.
Теперь кратко рассмотрим алгоритм, с помощью которого мы определяем,
в каком состоянии (единственной копии или реплицированном) находится объ-
ект. Изначально программа Огса состоит из одного процесса, владеющего всеми
объектами. Когда она разветвляется, все остальные машины уведомляются об
этом событии и получают текущие копии всех совместно используемых парамет-
ров дочерних процессов. Каждая исполняющая система подсчитывает стоимость
репликации этого объекта и сравнивает ее со стоимостью отказа от репликации.
Чтобы проделать эти вычисления, необходимо знать ожидаемое соотношение
операций чтения и записи. Компилятор оценивает это значение, исследуя про-
грамму и принимая во внимание, что вызовы из циклов стоят больше, а вызовы
из условных инструкций ~ меньше, чем обычные вызовы. Также в расчетах учи-
тываются затраты на взаимодействие. Например, объект с соотношением чте-
ние/запись 10 в сети с широковещательной рассылкой следует реплицировать,
а
объект с соотношением чтение/запись 1 в сети со сквозной (от точки к точке)
связью
—
хранить в состоянии единственной копии, причем эту копию следует
располагать на той машине, на которой выполняется большинство операций за-
писи. Более детальное описание этого процесса можно найти в [29].
Поскольку все исполняющие системы проделывают одни и те же вычисле-
ния, они приходят к одинаковому решению. Если объект постоянно находится
на одной машине, а нужен на всех, он становится распределенным. Если объект
реплицирован, а необходимость в этом уже исчезла, все машины, кроме одной.