- •7.5.2. Трехфазное подтверждение
- •7.6. Восстановление
- •7.6.1. Основные понятия
- •7.6.2. Создание контрольных точек
- •7.6.3. Протоколирование сообщений
- •7.7. Итоги
- •Глава 8
- •8.1. Общие вопросы защиты
- •8.1.1. Угрозы, правила и механизмы
- •8.1.2. Вопросы разработки
- •8.1.3. Криптография
- •8.2. Защищенные каналы
- •8.2.1. Аутентификация
- •8.2.2. Целостность и конфиденциальность сообщений
- •8.2.3. Защищенное групповое взаимодействие
- •8.3. Контроль доступа
- •8.3.1. Общие вопросы контроля доступа
- •8.3.2. Брандмауэры
- •8.3.3. Защита мобильного кода
- •8.4. Управление защитой
- •8.4.1. Управление ключами
- •8.4.2. Управление защищенными группами
- •8.4.3. Управление авторизацией
- •8.5. Пример — Kerberos
- •8.6. Пример — sesame
- •8.6.1. Компоненты системы sesame
- •8.6.2. Сертификаты атрибутов привилегий
- •8.7. Пример — электронные платежные системы
- •8.7.1. Электронные платежные системы
- •8.7.2. Защита в электронных платежных системах
- •8.7.3. Примеры протоколов
- •8.8. Итоги
- •Глава 9
- •9.1. Corba
- •9.1.1. Обзор
- •9.1.2. Связь
- •9.1.3. Процессы
- •9.1.4. Именование
- •9.1.5. Синхронизация
- •9.1.6. Кэширование и репликация
- •9.1.7. Отказоустойчивость
- •9.1.8. Защита
- •9.2. Dcom
- •9.2.1. Обзор
- •9.2.2. Связь
- •9.2.3. Процессы
- •9.2.4. Именование
- •Синхронизация
- •Репликация
- •Отказоустойчивость
- •9.2.8. Защита
- •9.3. Globe
- •9.3.1. Обзор
- •9.3.2. Связь
- •9.3.3. Процессы
- •9.3.4. Именование
- •9.3.5. Синхронизация
- •9.3.6. Репликация
- •Отказоустойчивость
- •9.4. Сравнение систем corba, dcom и Globe
- •9.4.1. Философия
- •Процессы
- •9.4.4. Именование
- •Синхронизация
- •Кэширование и репликация
- •Отказоустойчивость
7.6.2. Создание контрольных точек
В отказоустойчивых распределенных системах обратное исправление ошибок требует, чтобы система регулярно записывала свое состояние в устойчивое хранилище данных. Понятие состояния распределенных систем обсуждалось в главе 5. В частности, мы делали упор на необходимость записи непротиворечивого глобального состояния, называемого также распределенным снимком состояния (distributed snapshot). Если в распределенном снимке состояния процесс Р был сохранен в момент получения сообщения, должен также быть и процесс Q, сохраненный в момент передачи сообщения. Правда, в виде исключения сообщение может прийти и со стороны.
В схемах обратного исправления ошибок каждый процесс время от времени записывает свое состояние в локальное устойчивое хранилище. Для восстановления после системной ошибки необходимо из этих локальных состояний воссоздать непротиворечивое общее состояние. В частности, лучше всего восстановить последний распределенный снимок состояния, именуемый также границей восстановления (recovery line). Другими словами, граница восстановления соответствует последнему непротиворечивому срезу, что и показано на рис. 7.16.
Независимое создание контрольных точек
К сожалению, распределенная природа контрольных точек, когда каждый процесс просто время от времени записывает свое локальное состояние, никак не координируя свои действия с другими, может сильно затруднить поиски границы восстановления. Для нахождения границы восстановления необходимо, чтобы каждый из процессов откатился к последнему записанному состоянию. Если эти локальные состояния не образуют распределенного снимка состояния, потребуется новый откат и т. д. Этот процесс каскадного отката может привести к эффекту домино (domino effect), как показано на рис. 7.17.
При ошибке в процессе Р2 необходимо восстановить его состояние, каким оно было записано в последней контрольной точке. Процесс Р1 также придется откатывать. К сожалению, два последних записанных локальных состояния не образуют глобального непротиворечивого состояния: состояние, записанное в Р2, указывает на прием сообщения т, но ни один процесс не может быть назван его отправителем. Соответственно, Р2 нужно откатить к еще более раннему состоянию.
Однако следующее состояние, в котором будет восстановлен процесс Р2, также не может использоваться в качестве части распределенного снимка состояния. В этом случае процесс Р1 записан принимающим сообщение т', а событие его отправления записано снова не будет. Таким образом, появится необходимость откатить к более раннему состоянию также и процесс Р1. В этом примере получается, что границей восстановления на самом деле является исходное состояние системы.
Поскольку процессы создают локальные контрольные точки независимо друг от друга, этот метод называется также методом независимого создания контрольных точек (independent checkpointing). Альтернативой ему является глобально координированное создание контрольных точек, которое мы обсудим ниже. Однако координация требует глобальной синхронизации, которая может создать проблемы с производительностью. Другой недостаток независимого создания контрольных точек состоит в том, что любое локальное хранилище нужно время от времени чистить, например, запуская специальную программу «сборки мусора». Однако самый серьезный недостаток — это необходимость расчета границы восстановления.
Независимое создание контрольных точек требует записи зависимостей, чтобы процессы можно было откатить вместе, в непротиворечивое глобальное состояние. Для этого обозначим т-ю контрольную точку процесса Р как CP[i](m). Пусть INT[i](m) обозначает интервал между контрольными точками СР[г\(т-\) и CP[i](m).
Когда процесс Pi отправляет сообщение в интервале INT[i](m), он добавляет к нему пару (i,m), пересылая ее принимающему процессу. Когда процесс Pj получает сообщение в интервале INT[j](n) вместе с парой (i,m), он записывает зависимость INT[i](m) ->INT[j](n). Таким образом, когда Pj создает контрольную точку CP[j](n), он дополнительно вместе с прочей информацией для восстановления, входящей в CP[j](n), записывает в локальное хранилище данных и эту зависимость.
Предположим теперь, что в некоторый момент процесс Р1 необходимо откатить в контрольную точку CP[i](m-l). Для того чтобы гарантировать глобальную непротиворечивость, нам следует убедиться, что все процессы, получавшие от Р1 сообщения, посланные в интервале INT[i](m), откачены назад к состоянию, предшествующему получению этих сообщений. Так, например, процесс Pj в нашем примере следует откатить как минимум до контрольной точки CP[j](n-l). Если CP[j](n-i) не приведет систему в глобально непротиворечивое состояние, следует произвести дальнейший откат.
Расчет границы восстановления требует анализа интервальных зависимостей, сохраненных каждым из процессов при создании контрольных точек. Если даже не входить в дополнительные детали, это делает такие вычисления достаточно сложными и не убеждает нас в преимуществах независимого создания контрольных точек по сравнению с координированным созданием. Кроме того, как оказалось, часто основным фактором, влияющим на производительность, оказывается не координация процессов, а затраты, вызываемые хранением состояния в локальных устойчивых хранилищах (см., например, [136]). Поэтому координированное создание контрольных точек, которое значительно проще их независимого создания, становится все более популярным.
Координированное создание контрольных точек
В соответствии с названием, при координированном создании контрольных точек {coordinated checkpointing) все процессы синхронизированы для того, чтобы запись их состояний в локальные устойчивые хранилища происходила одновременно. Основное преимущество координированного создания контрольных точек состоит в том, что записанное состояние автоматически получается глобально непротиворечивым, что позволяет избежать каскадного отката, приводящего к эффекту домино. Для координированного создания контрольных точек может использоваться алгоритм распределенного снимка состояния, который мы обсуждали в главе 5. Этот алгоритм представляет собой пример неблокирующей координации контрольных точек.
Самым простым решением считается использование двухфазного протокола блокировки. Сначала координатор рассылает всем процессам сообщение CHECKPOINT_REQUEST. Когда процесс получает это сообщение, он создает локальную контрольную точку, начинает выстраивать в очередь все последующие сообщения, приходящие к нему от работающего приложения, и отправляет координатору подтверждение создания контрольной точки. После того как координатор получит подтверждения от всех процессов, он рассылает сообщение CHECKPOINT_DONE, позволяющее блокированным процессам продолжить выполнение.
Легко заметить, что такой подход также приводит к записи глобально непротиворечивого состояния, поскольку никакие входящие сообщения не становятся частью состояния контрольной точки. Это происходит потому, что никакие сообщения, следующие за запросом на создание контрольной точки, не считаются частью локальной контрольной точки. В то же время исходящие сообщения (посылаемые процессом, для которого создается контрольная точка, работающим приложениям) сохраняются в локальной очереди до прихода сообщения CHECK-POINT_DONE.
Усовершенствованием этого алгоритма является групповая рассылка запроса на создание контрольных точек только тем процессам, которые зависят от восстановления координатора. Процесс зависит от координатора, если он получает сообщение, которое прямо или косвенно причинно связано с сообщением, отправленным координатором с момента создания предыдущей контрольной точки. Это приводит нас к понятию инкремеитиого снимка состояния (incremental snapshot).
Для получения инкрементного снимка состояния координатор рассылает запрос на создание контрольных точек только тем процессам, которым он с момента создания предыдущей контрольной точки посылал сообщения. Когда процесс Р получает такой запрос, он рассылает его всем прочим процессам, которым с момента создания предыдущей контрольной точки посылал сообщения он сам и т. д. Процесс рассылает запрос только один раз. Когда будут определены все процессы, производится вторая групповая рассылка, чтобы закончить создание контрольных точек и запустить выполнение процессов с того места, где они были остановлены.
