From bbf57bc195146aa4b8d05117c6015b7f096cca50 Mon Sep 17 00:00:00 2001 From: Vladimir Protsenko Date: Sun, 4 Dec 2022 15:14:52 +0400 Subject: [PATCH] Added 2PC Zookeeper description. --- L4 - ZooKeeper/hints.md | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 L4 - ZooKeeper/hints.md diff --git a/L4 - ZooKeeper/hints.md b/L4 - ZooKeeper/hints.md new file mode 100644 index 0000000..40a5870 --- /dev/null +++ b/L4 - ZooKeeper/hints.md @@ -0,0 +1,55 @@ +# Подсказки к упражениям + + +## Двухфазный коммит протокол на основе ZooKeeper +На основе материалов: https://zookeeper.apache.org/doc/r3.4.2/recipes.html#sc_recipes_twoPhasedCommit и https://stackoverflow.com/questions/24635777/how-to-implement-2pc-in-zookeeper-cluster + +Протокол двухфазной коммита — это алгоритм, позволяющий всем клиентам в распределенной системе договориться либо о коммите транзакции, либо о ее откате. + +Взаимодействующие компоненты: +- создатель транзакции, +- координатор транзакции, +- исполнители транзакции, +- zookeeper, +- (опционально) прямой канал связи создателя транзакции и координатора, +- (опционально) прямые каналы связи между координатором и исполнителями. + +### Вариант 1. + +В ZooKeeper вы можете реализовать двухфазный коммит протокол, если координатор создаст узел транзакции, скажем "/app/Tx", и один дочерний узел для каждого исполнителя транзакции, скажем "/app/Tx/node_i". Когда *координатор* создает дочерний узел, он оставляет его содержимое неопределенным. + +Первая фаза: + +Как только каждый исполнитель, участвующий в транзакции, получает транзакцию от координатора, исполнитель читает каждый дочерний узел "node_i" и подписывается на события изменения транзакционного узла. Затем каждый исполнитель обрабатывает запрос и принимает решение "commit" или "abort", записывая данные в свой узел. + +Вторая фаза: + +Как только запись завершается, другие исполнители получают уведомление, и как только все исполнители получат все голоса, они могут принять решение либо "commit", либо "abort". Обратите внимание, что узел может принять решение абортировать транзакцию раньше, если какой-либо исполнитель проголосует за "abort". + +Интересным аспектом этой реализации является то, что единственная роль координатора заключается в определении группы исполнителей, создании узлов ZooKeeper и распространении транзакции на соответствующим исполнителям. Фактически, даже распространение транзакции может быть сделано через ZooKeeper путем записи в узле транзакции. + +У описанного выше подхода есть два важных недостатка: +— это сложность сообщений, которая составляет O(n²). +— невозможность обнаружения аварийного завершения исполнителей. + +Для решения первой проблемы можно сделать так, чтобы об изменениях в узлах транзакций уведомлялся только координатор, а затем уведомлять исполнителей, как только координатор примет решение. Обратите внимание, что этот подход остаётся масштабируемым, но он медленнее, поскольку требует, чтобы все коммуникации проходили через координатора. + +Для решения второй проблемы можно сделать так, чтобы координатор распространял транзакцию исполнителям, а каждый исполнитель создавал свой собственный эфемерный узел. + +### Вариант 2. + +1. Координатор C регистрирует транзакционный узел /app/tx + +Первая фаза: + +2. Координатор уведомляет исполнителей о транзакции +3. Координатор подписывается на изменения транзакционного узла (устанавливает WATCH на /app/tx) +4. Каждый исполнитель создает эфемерных узел /app/tx/node_i с решением commit/abort +5. Исполнитель подписывается на события своего узла для получения решения от координатора ( вторая фаза ) + +Вторая фаза: + +6. Координатор принимает решение о commit/abort после ожидания таймаута или после создания всех узлов исполнителей с решением commit +7. Координатор изменяет значение эфемерных узлов для каждого исполнителя на commit / abort +8. Исполнители применяют / прерывают транзакцию +9. Исполнители обновляют значение узла на committed \ No newline at end of file