2 Phase Commit — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Новая страница: «'''Алгоритм двухфазного коммита''' — классический централизованный оптимистичный алгори…»)
 
м (rollbackEdits.php mass rollback)
 
(не показано 11 промежуточных версий 2 участников)
Строка 1: Строка 1:
 +
[[Категория: Параллельное программирование]]
 
'''Алгоритм двухфазного коммита''' — классический централизованный оптимистичный алгоритм распределённого консенсуса из баз данных для подтверждения [[Транзакции в распределённых системах|распределённых транзакций]].
 
'''Алгоритм двухфазного коммита''' — классический централизованный оптимистичный алгоритм распределённого консенсуса из баз данных для подтверждения [[Транзакции в распределённых системах|распределённых транзакций]].
  
После того, как мы завершили транзакцию, её надо атомарно подтвердить на всех участниках.
+
После того, как мы завершили транзакцию, её надо атомарно подтвердить на всех участниках (participants).
 
У каждой транзакции есть выделенный координатор (transaction coordinator).
 
У каждой транзакции есть выделенный координатор (transaction coordinator).
 
Алгоритм работает в две фазы:
 
Алгоритм работает в две фазы:
  
1. '''Запрос (request)''': координатор спрашивает каждого участника: "готов ли ты ''очень быстро'' завершить транзакцию?". Если кто-нибудь ответил "нет", то отменяем транзакцию. Если кто-то отвечает "да", то он должен уметь обеспечить завершение транзакции даже если упадёт и поднимается (например, все данные уже в журнале).
+
# '''Запрос (request)''': координатор спрашивает каждого участника: "готов ли ты ''очень быстро и гарантированно'' завершить транзакцию?". Если кто-нибудь ответил "нет", то отменяем транзакцию. Если кто-то отвечает "да", то он должен уметь обеспечить завершение транзакции даже если упадёт и поднимается (например, все данные уже в журнале).
2. '''Завершение''': координатор принимает решение о закреплении (commit) или отмене (rollback) транзакции и записывает его в свою надёжную память, после чего рассылает всем решение. После этого можно сообщить о фиксации транзакции.
+
# '''Завершение''': координатор принимает решение о закреплении (commit) или отмене (rollback) транзакции и записывает его в свою надёжную память, после чего рассылает всем решение. После рассылки можно сообщить о фиксации транзакции, подтверждения от участников ждать не нужно (но тогда может быть проблема с тем, что следующие чтения из СУБД будут возвращать старые данные, пока не закоммитили).
 +
 
 +
При этом проблемы двух генералов на практике обычно нет: после того, как координатор принял решение о транзакции, он будет его доносить до всех любопытствующих узлов.
 +
 
 +
Всего на коммит требуется $3N$ сообщений ($N$ — количество участников транзакции) и задержка порядка $3\cdot RTT$ (round-trip time).
  
 
== Ограничения ==
 
== Ограничения ==
 +
Так как это алгоритм консенсуса, к нему применима [[Теорема Фишера-Линча-Патерсона (FLP)|FLP]].
 +
 +
Если у нас есть отказы узлов или связи, то 2PC будет ждать, пока связь не восстановится:
 +
* Если отказ произошёл на первой фазе, то координатор может отменить транзакцию по таймауту.
 +
* После того, как координатор перешёл на вторую фазу, он не имеет права успокоиться, пока не донесёт своё решение до всех узлов.
 +
* Если узел отказал, а потом восстановился, то он спрашивает координатора, какое решение было принято. Если "да", то обязан закрепить транзакцию (т.е. координатор должен хранить все подтверждённые транзакции, которые подтвердили не все узлы).
 +
* Если отказал координатор, то, если узел ответил "да", он не имеет права забить на транзакцию, пока координатор не восстановится.
 +
 +
Но алгоритм классический, простой, на практике неплохо работает, потому что сложно только с отказами координатора и отказами узлов на второй фазе (когда решение о коммите уже принято), а такое бывает не так часто.

Текущая версия на 19:30, 4 сентября 2022

Алгоритм двухфазного коммита — классический централизованный оптимистичный алгоритм распределённого консенсуса из баз данных для подтверждения распределённых транзакций.

После того, как мы завершили транзакцию, её надо атомарно подтвердить на всех участниках (participants). У каждой транзакции есть выделенный координатор (transaction coordinator). Алгоритм работает в две фазы:

  1. Запрос (request): координатор спрашивает каждого участника: "готов ли ты очень быстро и гарантированно завершить транзакцию?". Если кто-нибудь ответил "нет", то отменяем транзакцию. Если кто-то отвечает "да", то он должен уметь обеспечить завершение транзакции даже если упадёт и поднимается (например, все данные уже в журнале).
  2. Завершение: координатор принимает решение о закреплении (commit) или отмене (rollback) транзакции и записывает его в свою надёжную память, после чего рассылает всем решение. После рассылки можно сообщить о фиксации транзакции, подтверждения от участников ждать не нужно (но тогда может быть проблема с тем, что следующие чтения из СУБД будут возвращать старые данные, пока не закоммитили).

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

Всего на коммит требуется $3N$ сообщений ($N$ — количество участников транзакции) и задержка порядка $3\cdot RTT$ (round-trip time).

Ограничения

Так как это алгоритм консенсуса, к нему применима FLP.

Если у нас есть отказы узлов или связи, то 2PC будет ждать, пока связь не восстановится:

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

Но алгоритм классический, простой, на практике неплохо работает, потому что сложно только с отказами координатора и отказами узлов на второй фазе (когда решение о коммите уже принято), а такое бывает не так часто.