В настоящее время, когда большинство интернет-компаний разрабатывают общую структуру, они будут делить систему на множество небольших систем в соответствии с бизнес-модулями, такими как система заказов, система карт и купонов, платежная система и т. д. Короче говоря, это разделяй и властвуй, так что каждый Вы можете сосредоточиться на поддержке собственного кода. Тогда разные малые системы разрабатываются, тестируются и запускаются сами по себе, и они не будут сопряжены с другими, а могут выполняться самостоятельно, что очень удобно и значительно упрощает стоимость разработки больших систем.
Однако как реализовать распределенные транзакции при наличии нескольких подсистем? Ниже описаны несколько реализаций распределенных транзакций.
Во-первых, концепция распределенных транзакций.
Распределенная транзакция относится к тому, как запрос обеспечивает согласованность данных в цепочке вызовов нескольких систем. Например, запрос на оплату после успешного платежа перезвонит, чтобы запросить систему заказов об изменении статуса заказа, и перезвонит в систему запроса карты и купона, чтобы изменить статус карты и купона. Затем, если запрос обратного вызова потерян по сетевым причинам, пользователь, возможно, оплатил, заказ по-прежнему отображается как неоплаченный, а карта и купон по-прежнему заморожены и не могут быть установлены как использованные.
Два, 2 шт. / 3 шт. / TCC и другие распределенные протокол транзакций
Протокол двухфазной фиксации 2PC
2PC — очень классический строго согласованный и централизованный протокол атомарной фиксации, который определяет два типа узлов: централизованный узел-координатор и несколько узлов-участников. 2PC делится на две фазы:
этап подготовки:
1. Координатор отправляет содержимое транзакции всем участникам, спрашивает, можно ли отправить транзакцию, и ждет ответа от всех участников.
2. Каждый участник выполняет операции с транзакциями и записывает информацию об отмене и повторении в журнале транзакций (но не фиксирует транзакцию).
3. Если участник успешно выполняется, обратная связь ДА для координатора, который можно отправить; если выполнение не удается, обратная связь NO для координатора, то есть нельзя представить.
Сцена фиксации:
(Все участники ответили ДА)
1. Координатор отправляет формальный запрос на транзакцию (т.е. запрос на фиксацию) всем участникам.
2. Участник выполняет запрос Commit и освобождает ресурсы, занятые в течение всей транзакции.
3. Каждый участник возвращает координатору сообщение о завершении подтверждения.
4. После того, как координатор получит сообщения Ack, отправленные всеми участниками, транзакция будет отправлена.
(Любой отзыв участника НЕТ)
1. Координатор рассылает всем участникам запрос на откат (т.е. запрос на откат).
2. Участник использует информацию об отмене в фазе 1 для выполнения операции отката и освобождения ресурсов, занятых в течение всей транзакции.
3. Каждый участник возвращает координатору сообщение о завершении подтверждения.
4. После того, как координатор получит сообщения Ack, отправленные всеми участниками, транзакция прерывается.
2PC столкнется с некоторыми проблемами во время двухэтапного процесса отправки:
1. Проблемы с производительностью. Из процесса мы видим, что его самым большим недостатком является то, что в середине его выполнения все узлы блокируются. Каждый узел, работающий с базой данных, в это время занимает ресурсы базы данных. Только когда все узлы будут готовы, координатор транзакции уведомит о глобальной фиксации, а участники освободит ресурсы после фиксации локальной транзакции. Такой процесс будет относительно длительным и сильно повлияет на производительность.
2, координатор единых точек отказа. Координатор транзакций является ядром модели XA, после того как узел координатора транзакций повесит трубку, участники не получат уведомление о совершении или откате, в результате чего состояние узла участника всегда находится в середине транзакции, которая не может быть завершена.
3. Несоответствие данных, вызванное потерянными сообщениями. На втором этапе при возникновении проблемы в локальной сети часть участников транзакции получает сообщение фиксации, а часть участников транзакции не получает сообщение фиксации, что приведет к несогласованности данных между узлами.
Протокол трехфазной фиксации 3PC
Улучшенная версия 2PC, которая добавляет фазу CanCommit к двухфазной фиксации и вводит механизм тайм-аута. Как только участник транзакции не получил запрос на фиксацию координатора, он автоматически выполнит локальную фиксацию, что относительно эффективно решает проблему единой точки отказа координатора. .
Фаза 1: можно зафиксировать
1. Координатор отправляет запрос CanCommit, содержащий содержимое транзакции, всем участникам, спрашивая, может ли транзакция быть зафиксирована, и ожидает ответа от всех участников.
2. После того, как участник получит запрос CanCommit, если он считает, что операция транзакции может быть выполнена, он вернет YES и войдет в состояние подготовки, в противном случае он вернет NO.
Фаза 2: предварительная фиксация
Предоставление транзакции: (все участники возвращаются да)
1. Координатор отправляет всем участникам запрос PreCommit для входа в стадию подготовки.
2. После того, как участник получает запрос PreCommit, выполняется транзакционная операция, и в журнал транзакций записывается информация Undo и Redo (но транзакция не фиксируется).
3. Каждый участник возвращает координатору ответ «Подтверждение» или «Нет» и ожидает окончательной инструкции.
Прервать транзакцию: (любой отзыв участника НЕТ, или координатор не может получить отзыв от всех участников после ожидания тайм-аута)
1. Координатор отправляет всем участникам запрос на прерывание.
2. Независимо от получения от координатора запроса на прерывание или тайм-аут ожидания запроса координатора, участник прервет транзакцию.
Этап 3: Совершение
Зафиксировать транзакцию: (когда все участники отправят ответ Ack)
1. Если координатор находится в рабочем состоянии, отправьте запрос на фиксацию всем участникам.
2. После того, как участник получит запрос на выполнение транзакции, фиксация транзакции будет формально выполнена, и ресурсы, занятые в течение всей транзакции, будут освобождены.
3. Каждый участник возвращает координатору сообщение о завершении подтверждения.
4. После того, как координатор получит сообщения Ack, отправленные всеми участниками, транзакция будет отправлена.
Прервать транзакцию: (любой отзыв участника НЕТ, или координатор не может получить отзыв от всех участников после ожидания тайм-аута)
1. Если координатор работает, отправьте всем участникам запрос на прерывание.
2. Участник использует информацию об отмене в фазе 1 для выполнения операции отката и освобождения ресурсов, занятых в течение всей транзакции.
3. Каждый участник возвращает координатору сообщение о завершении подтверждения.
4. После того, как координатор получит сообщения Ack, отправленные всеми участниками, транзакция прерывается.
TCCСоглашение о компенсационной сделке
TCC разделяет отправку транзакций на 3 операции: Try — Confirm — Cancel.
1. Попробуйте: зарезервированные бизнес-ресурсы/проверка данных
2, подтвердите: подтвердите выполнение бизнес-операции
3. Отмена: отменить выполнение бизнес-операций.
Процесс обработки транзакций TCC аналогичен двухэтапной фиксации 2PC, но 2PC обычно выполняется на уровне БД между базами данных, а TCC, по сути, представляет собой 2PC уровня приложения.
3. Сценарии использования распределенных транзакций
1. Транзакция на основе реализации сообщения
Транзакция на основе сообщения подходит для фиксации или отката распределенной транзакции, зависит только от бизнес-потребностей инициатора транзакции, а изменения данных других источников данных следуют бизнес-сценарию инициатора.
2. Вознаграждение за реализацию сделки
Транзакции, основанные на сообщениях, не могут решить все бизнес-сценарии, например следующие сценарии: когда заказ выполнен, наличные деньги пользователя вычитаются одновременно.
Здесь инициатором транзакции является служба, которая управляет библиотекой заказов, но то, будет ли отправлена вся транзакция, не может быть определена только службой заказов, потому что необходимо убедиться, что у пользователя достаточно денег для завершения транзакции, и эта информация находится в службе управления денежной наличностью. Здесь мы можем ввести транзакцию, основанную на реализации компенсации, процесс которой выглядит следующим образом:
- Создайте данные заказа, но пока не отправляйте локальные транзакции
- Служба заказа отправляет удаленный вызов в кассовую службу для удержания соответствующей суммы
- После успешного выполнения вышеуказанных шагов отправьте транзакцию библиотеки заказов.
Вышеуказанное является нормальным и успешным процессом.Если ненормальный процесс необходимо откатить, в кассовую службу будет отправлен дополнительный удаленный вызов для добавления ранее вычтенной суммы.
Вышеупомянутый процесс сложнее, чем процесс транзакции, основанный на реализации очереди сообщений, и рабочая нагрузка разработки также больше:
- Написать логику создания заказа в сервисе заказов
- Напишите логику для списания денег в кассе
- Напишите логику возврата компенсации в кассовом сервисе
Видно, что процесс транзакции является более сложным, чем распределенная транзакция, основанная на реализации сообщений, и необходимо разработать дополнительные соответствующие методы отката бизнеса, а функция пикового сглаживания и заполнения долины трафика между сервисами теряется. Но это лишь немногим сложнее, чем транзакция на основе сообщений.Если нельзя использовать транзакцию эвентуальной согласованности на основе очереди сообщений, приоритет может быть отдан форме транзакции на основе компенсации.
3. 2ПК дела
Он подходит для сценариев, когда участников мало, время выполнения одной локальной транзакции мало, а доступность самих участников высока, в противном случае велика вероятность серьезного снижения производительности.