главная/Распределённые транзакции и консенсус. 2PC, 3PC
2PC 3PC

Распределённые транзакции и консенсус. 2PC, 3PC

Что вообще такое распределённые транзакции.

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

Например:

  • У тебя есть банк с двумя филиалами: Москва и Берлин.
  • Клиент переводит €100 со счёта в Москве на счёт в Берлине.

Мы хотим, чтобы не получилось ситуации:

  • деньги списались в Москве,
  • но не зачислились в Берлине.

Как это решают — 2-фазный коммит (2PC)

Это протокол, который помогает нескольким узлам договориться о том, применить ли транзакцию.

Фаза 1 — “Готовность” (prepare)

  1. Центральный координатор говорит всем участникам:
    “Готовы выполнить эту операцию?”
  2. Каждый узел проверяет у себя (например, хватает ли баланса, нет ли ошибок)
    и отвечает “Да” или “Нет”.

Фаза 2 — “Подтверждение” (commit)

  1. Если все сказали “Да”, координатор говорит: “Коммитим!”.
  2. Если хотя бы один сказал “Нет”, координатор говорит: “Откатываемся!”.

Пример:

Москва (узел A): снять €100
Берлин (узел B): зачислить €100

Координатор:
спрашивает у обоих “готовы?”
получает ответы:

  • A: “Да”
  • B: “Да”
    отправляет команду: “Коммитим!”

Всё ок — транзакция выполнена.

Но проблема — если координатор завис?

Если координатор упал между шагами 1 и 2, узлы остаются “в подвешенном состоянии”:
они уже “готовы”, но не знают, надо ли коммитить или откатывать.

Это может привести к зависшим транзакциям, которые ждут решения бесконечно.

Трёхфазный коммит (3PC)

Чтобы избежать зависаний, придумали трёхфазный коммит (Three-Phase Commit).
Он добавляет дополнительную фазу, чтобы участники могли действовать,
даже если координатор потерялся.

Фаза 1 — “Можно ли?” (CanCommit)

Координатор спрашивает:

“Можете ли вы выполнить операцию?”
Участники проверяют и отвечают “Да” или “Нет”.

Фаза 2 — “Готовьтесь” (PreCommit)

Если все ответили “Да”, координатор говорит:

“Готовьтесь к коммиту, но пока не применяйте!”
Участники сохраняют изменения в журнале, но не делают их окончательными.

Теперь, если координатор упадёт, участники знают, что коммит почти точно будет
и могут договориться между собой — завершить или откатить.

Фаза 3 — “Коммитим!” (DoCommit)

Когда координатор уверен, он рассылает команду:

“Коммитим окончательно!”

Пример:

  1. Координатор: “Можете перевести 100 евро?”
  2. Оба узла отвечают “Да”.
  3. Координатор: “Окей, готовьтесь — почти коммитим.”
  4. Узлы записывают данные как “подготовленные”.
  5. Координатор: “Коммитим!”
  6. Узлы применяют изменения.

Если координатор пропал после шага 3,
узлы могут согласовать между собой, что раз все были готовы — можно завершить.

Это делает систему более живучей, чем 2PC.
Но если сеть сильно тормозит или узлы не успели обменяться — конфликт всё ещё возможен.

Что такое консенсус (Consensus)

Консенсус — это более надёжный способ, при котором все узлы
договариваются о решении вместе, даже если часть системы падает.

Здесь уже нет одного “всемогущего координатора”,
а решения принимаются голосованием и фиксацией большинства.

Пример:

Три сервера решают: “Коммитим или нет?”

  • A говорит: “Коммитим”.
  • B говорит: “Коммитим”.
  • C недоступен.

Двое из трёх согласны → Коммитим.

Даже если один узел отвалился, большинство решает исход.

Как это реализуют — Paxos / Raft

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

  • Сервер A становится лидером.
  • Клиент отправляет ему запрос: “x = 1”.
  • A рассылает обновление B и C.
  • Когда большинство подтвердили (2 из 3) — команда зафиксирована.
  • Даже если один сервер упадёт, данные сохраняются.

Если лидер упал — выбирается новый, и система продолжает работу.

Почему консенсус лучше коммитов

  • Нет “единой точки отказа” — система переживает падение узлов.
  • Большинство узлов всегда могут принять решение.
  • Нет зависаний, как в 2PC.
  • Сложнее реализовать, но надёжнее при сбоях сети.