Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
440-620.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
4.13 Mб
Скачать

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).

Для получения инкрементного снимка состояния координатор рассылает за­прос на создание контрольных точек только тем процессам, которым он с момен­та создания предыдущей контрольной точки посылал сообщения. Когда процесс Р получает такой запрос, он рассылает его всем прочим процессам, которым с мо­мента создания предыдущей контрольной точки посылал сообщения он сам и т. д. Процесс рассылает запрос только один раз. Когда будут определены все процес­сы, производится вторая групповая рассылка, чтобы закончить создание кон­трольных точек и запустить выполнение процессов с того места, где они были остановлены.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]