Подтвердить что ты не робот

Двухфазное принятие

Я считаю, что большинство людей знают, что такое 2PC (двухфазный протокол фиксации) и как использовать его в Java или большинстве современных языков. В основном, он используется, чтобы убедиться, что транзакции синхронизированы, когда у вас есть 2 или более БД.

Предположим, у меня есть две базы данных (A и B) с использованием 2PC в двух разных местах. Прежде чем A и B готовы совершить транзакцию, обе БД сообщают менеджеру транзакций о том, что они готовы к фиксации. Таким образом, когда менеджер транзакций будет подтвержден, он отправит сигнал обратно в и B, чтобы они пошли дальше.

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

Помните, что A зафиксировано, но B нет, и мы используем 2PC (так, дизайн 2PC перестает работать, не так ли?)

4b9b3361

Ответ 1

В двухфазной фиксации

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

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

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

Чтобы B не справился в этой ситуации, он должен был подвергнуться катастрофическому сбою, который потерял данные или записи журнала. Менеджер транзакций все равно будет знать, что B не сообщил об успешной фиксации. 1

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

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

Приложение по-прежнему должно восстанавливаться после ошибки, но транзакция не может выйти из строя без уведомления о непостоянном состоянии приложения.

Семантика

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

  • Если диспетчер ресурсов или сеть опускается на этапе 2, менеджер транзакций будет продолжать опрос менеджера ресурсов до тех пор, пока он возвращается. Когда он снова подключается к диспетчеру ресурсов он сообщит RM о совершении транзакции. Если RM возвращает ошибка в строке "Неизвестный TxID" TM будет знать, что в RM есть проблема с потерей данных.

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

  • Если TM переходит в фазу 2, он блокирует клиента до тех пор, пока ТМ возвращается. Он уже сообщил о транзакции как компрометируемая и не фатальная ошибка должна быть представлена ​​клиенту, хотя он может блокироваться до тех пор, пока TM не вернется. ТМ будет по-прежнему иметь транзакцию в незафиксированном состоянии и опросить RM для фиксации, когда он возвращается.

События потери данных после транзакции в менеджерах ресурсов не обрабатываются менеджером транзакций и являются функцией устойчивости RM.

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

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

Ответ 2

Ваш сценарий не единственный, где все может пойти не так, как надо, несмотря на все усилия. Предположим, что A и B сообщают "готовность" к ТМ, а затем кто-то отключает линию между ТМ и, скажем, B. B ждет "добро" (или "нет" ) от ТМ, но он, безусловно, выиграл "продолжайте ждать до тех пор, пока TM не восстановится (его собственные ресурсы, вовлеченные в транзакцию, должны оставаться заблокированными/недоступными в течение всего времени ожидания по очевидным причинам). Поэтому, когда B ждет слишком долго для собственного вкуса, он будет принимать так называемые" эвристические решения". То есть, он решит совершить или откатиться независимо от ТМ, на основании, ну, я действительно не знаю, что, но это не имеет большого значения. Должно быть очевидно, что любые такие эвристические решения могут отклоняться от фактического принятия решения, принятого TM.

Ответ 3

Я считаю, что трехступенчатая фиксация - намного лучший подход. К сожалению, я не нашел никого, кто применял бы такую ​​технологию.

http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/

Вот основные части этой статьи:

Основная трудность с 2PC заключается в том, что после того, как решение о совершении было принято координатором и передано некоторым репликам, реплики идут прямо вперед и действуют на инструкцию фиксации, не проверяя, была ли получена каждая другая реплика сообщение. Затем, если реплика, которая совершила сбой вместе с координатором, система не может сказать, каков результат транзакции (поскольку только координатор и реплика, получившие сообщение, точно знают). Поскольку транзакция, возможно, уже была зафиксирована в разбитой реплике, протокол не может пессимистически прерываться - поскольку транзакция может иметь побочные эффекты, которые невозможно отменить. Точно так же протокол не может оптимистически заставить транзакцию совершить, поскольку первоначальное голосование могло быть отменено.

Эта проблема - в основном - обойдена добавлением дополнительной фазы к 2PC, что неудивительно дает нам трехфазный протокол фиксации. Идея очень проста. Мы разбиваем вторую фазу 2PC - "совершать" на две подфазы. Первый - это "подготовка к фазе принятия". Координатор отправляет это сообщение всем репликам, когда он получил единодушные "да голоса" на первом этапе. При получении этих сообщений реплики попадают в состояние, в котором они могут совершить транзакцию, - принимая необходимые блокировки и т.д. - но, тем не менее, не выполняют никакой работы, которую они не могут впоследствии отменить. Затем они отвечают координатору, сообщая ему, что получено сообщение "подготовить сообщение для совершения".

Цель этой фазы - передать результат голосования каждой реплике, чтобы состояние протокола могло быть восстановлено независимо от того, какая копия умирает.

Последняя фаза протокола выполняет почти то же самое, что и исходная фаза фиксации или прерывания в 2PC. Если координатор получает подтверждение доставки "подготовить для передачи сообщения от всех реплик", тогда безопасно совершать транзакцию. Однако, если доставка не подтверждена, координатор не может гарантировать, что состояние протокола будет восстановлено, если оно потерпит крах (если вы терпите фиксированное число f сбоев, координатор может пойти вперед, как только он получил f + 1 подтверждения). В этом случае координатор прекратит транзакцию.

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

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