Как мы все знаем, база данных может достигатьместные дела, то есть вв той же базе, вы можете позволить набору операций выполняться правильно или вообще не выполняться. Здесь особо подчеркиваетсяместные дела, то есть текущая база данных может поддерживать транзакции только в одной базе данных. Однако текущая система часто использует архитектуру микросервисов, а бизнес-система имеет независимую базу данных, поэтому существует требование транзакции между несколькими базами данных, что называется «распределенной транзакцией». Итак, как нам реализовать распределенные транзакции, если текущая база данных не поддерживает транзакции между базами данных? В этой статье сначала будут рассмотрены основные концепции и теоретические основы распределенных транзакций, а затем представлены несколько часто используемых решений для распределенных транзакций. Без лишних слов, давайте начнем~
Что такое транзакция?
Транзакция состоит из набора операций. Мы надеемся, что этот набор операций может быть выполнен правильно. Если какой-либо шаг в этом наборе операций не удается, то необходимо выполнить откат ранее выполненных операций. То есть все операции в одной транзакции либо все выполняются правильно, либо ни одна из них не выполняется.
Четыре характеристики транзакций ACID
Когда дело доходит до дел, мы должны упомянуть о четырех известных характеристиках дел.
-
атомарность Атомарность требует, чтобы транзакция была неделимой единицей выполнения, и все операции в транзакции либо выполнялись, либо не выполнялись вообще.
-
последовательность Согласованность требует, чтобы ограничения целостности базы данных не нарушались до и после начала и окончания транзакции.
-
изоляция Транзакции выполняются независимо друг от друга, они не мешают друг другу, и одна транзакция не видит данные другой запущенной транзакции.
-
Упорство Требования к сохраняемости: после завершения транзакции результат выполнения транзакции должен быть сохранен. Даже в случае сбоя базы данных результаты фиксации транзакций не будут потеряны после восстановления базы данных.
Примечание. Транзакции гарантируют только базу данных.Высокая надежность, то есть после возникновения проблемы в самой базе данных данные, представленные транзакцией, все еще могут быть восстановлены; и если это не сбой самой базы данных, например, поврежденный жесткий диск, данные, отправленные транзакцией, могут быть восстановлены. Потерянный. Это принадлежит "высокая доступность' категория. Следовательно, транзакции могут гарантировать только «высокую надежность» базы данных, а «высокая доступность» требует взаимодействия всей системы.
уровень изоляции транзакций
Чтобы расширить здесь, транзакцияизоляцияСделайте подробное объяснение.
Среди четырех основных характеристик транзакций ACID необходимая изоляция — это изоляция в строгом смысле, то есть несколько транзакций выполняются последовательно без какого-либо вмешательства друг в друга. Это действительно может полностью гарантировать безопасность данных, но в реальных бизнес-системах производительность этого метода невысока. Таким образом, база данных определяет четыре уровня изоляции, и уровень изоляции обратно пропорционален производительности базы данных: чем ниже уровень изоляции, тем выше производительность базы данных, а чем выше уровень изоляции, тем хуже производительность базы данных.
Проблемы с параллельным выполнением транзакций
Давайте сначала рассмотрим проблемы, которые могут возникнуть с базой данных при разных уровнях изоляции:
-
обновление потеряно Когда две одновременно выполняемые транзакции обновляют одну и ту же строку данных, возможно, что одна транзакция перезапишет обновление другой транзакции. Происходит, когда в базе данных нет операций блокировки.
-
грязное чтение Транзакция считывает данные из другой транзакции, которая еще не была зафиксирована. Данные могут быть отброшены и стать недействительными. Ошибка возникает, если первая транзакция принимает неверные данные для обработки.
-
неповторяемое чтение Смысл неповторяемости: транзакция дважды считывает одну и ту же строку данных, но получает разные результаты. Он делится на следующие два случая:
- Виртуальное чтение: в процессе чтения одной и той же записи транзакцией 1 дважды транзакция 2 изменяет запись, так что транзакция 1 считывает другую запись во второй раз.
- Фантомное чтение: во время двух запросов транзакции 1 транзакция 2 выполняет операции вставки и удаления в таблице, поэтому результат второго запроса транзакции 1 изменяется.
В чем разница между неповторяемым чтением и грязным чтением? Грязные чтения считывают незафиксированные данные, в то время как неповторяющиеся чтения считывают зафиксированные данные, но данные были изменены другой транзакцией во время двух чтений.
Четыре уровня изоляции базы данных
База данных имеет следующие четыре уровня изоляции:
-
Читать незафиксированные На этом уровне, когда транзакция изменяет строку данных, другой транзакции не разрешается изменять строку данных, но другой транзакции разрешено читать строку данных. Поэтому на этом уровне не будет потери обновлений, но будут происходить грязные чтения и неповторяющиеся чтения.
-
Чтение зафиксировано На этом уровне незафиксированная транзакция записи не позволяет другим транзакциям получить доступ к строке, поэтому грязное чтение отсутствует; однако транзакция, считывающая данные, позволяет другим транзакциям получить доступ к данным строки, поэтому происходит неповторяемое чтение.
-
Повторяемое чтение Повторяемое чтение На этом уровне транзакции чтения запрещают транзакции записи, но транзакции чтения разрешены, поэтому не бывает ситуации, когда одна и та же транзакция дважды считывает разные данные (неповторяющиеся чтения), а транзакции записи запрещают все остальное.
-
Сериализуемая сериализация Этот уровень требует, чтобы все транзакции выполнялись последовательно, чтобы избежать всех проблем, вызванных параллелизмом, но он очень неэффективен.
Чем выше уровень изоляции, тем лучше можно гарантировать целостность и согласованность данных, но тем больше влияние на параллельную производительность. Для большинства приложений предпочтительнее установить уровень изоляции системы базы данных на Read Committed. Он избегает грязных чтений и имеет хорошую производительность параллелизма. Хотя это может привести к проблемам параллелизма, таким как неповторяющееся чтение, фантомное чтение и второстепенные потерянные обновления, в отдельных случаях, когда такие проблемы могут возникать, приложение может управлять ими с помощью пессимистической блокировки или оптимистической блокировки.
Что такое распределенная транзакция?
До сих пор все представленные транзакции были локальными транзакциями, основанными на одной базе данных. Текущая база данных поддерживает только транзакции с одной базой данных и не поддерживает транзакции между базами данных. С популяризацией микросервисной архитектуры крупномасштабная бизнес-система часто состоит из нескольких подсистем, и эти подсистемы имеют свои собственные независимые базы данных. Часто бизнес-процесс должен выполняться несколькими подсистемами, и эти операции может потребоваться выполнить в транзакции. В микросервисных системах эти бизнес-сценарии встречаются повсеместно. На этом этапе нам необходимо реализовать поддержку транзакций между базами данных с помощью некоторых средств поверх базы данных, что часто называют «распределенными транзакциями».
Вот типичный пример распределенной транзакции — процесс заказа пользователя. Когда наша система принимает микросервисную архитектуру, система электронной коммерции часто делится на следующие подсистемы: товарная система, система заказов, платежная система, система баллов и т. д. Весь процесс заказа выглядит следующим образом:
- Пользователь просматривает продукты через систему продуктов, и когда он видит определенный продукт, он нажимает, чтобы разместить заказ.
- В этот момент система заказов сгенерирует заказ
- После успешного создания заказа платежная система предоставляет функцию оплаты
- Когда платеж будет завершен, система баллов добавит баллы пользователю.
Описанные выше шаги 2, 3 и 4 необходимо выполнить в одной транзакции. Для традиционных монолитных приложений очень просто реализовать транзакции, просто поместите эти три шага в метод A, а затем пометьте метод аннотацией Spring @Transactional. Spring гарантирует, что эти шаги либо все выполняются, либо не выполняются через поддержку транзакций базы данных. Но в этой микросервисной архитектуре эти три шага включают три системы и три базы данных.На данный момент мы должны внедрить некую черную технологию между базой данных и системой приложений для поддержки распределенных транзакций.
теория CAP
Теория CAP утверждает, что в распределенной системе могут быть удовлетворены не более двух требований C, A и P.
Значение КАП:
- C: Последовательность Последовательность Несколько копий одних и тех же данных идентичны в реальном времени.
- А: Доступность Доступность: в течение определенного периода времени система возвращает четкий результат, система называется доступной.
- P: Устойчивость к сбоям разделов Отказоустойчивость разделов Распространение одной и той же службы на несколько систем гарантирует, что когда одна система выйдет из строя, другие системы по-прежнему будут предоставлять ту же услугу.
Теория CAP говорит нам, что в распределенной системе мы можем выбрать не более двух из трех условий C, A и P. Так вот вопрос, какие два условия больше подходят для выбора?
Для бизнес-системы доступность и отказоустойчивость разделов — это два условия, которые должны быть выполнены, и они дополняют друг друга. Есть две основные причины, по которым бизнес-системы используют распределенные системы:
-
Улучшить общую производительность Когда объем бизнеса растет и один сервер больше не может удовлетворить потребности нашего бизнеса, нам нужно использовать распределенную систему и использовать несколько узлов для выполнения одной и той же функции, тем самым повышая производительность системы в целом.Это первый метод. использования распределенной системы.одна причина.
-
Достижение допуска разделения Если один узел или несколько узлов находятся в одной и той же сетевой среде, существуют определенные риски: если аппаратная комната отключится или произойдет стихийное бедствие, бизнес-система будет полностью парализована. Чтобы предотвратить эту проблему, используется распределенная система, а несколько подсистем распределяются по разным регионам и разным компьютерным залам, чтобы обеспечить высокую доступность системы.
Это показывает, что отказоустойчивость раздела является основой распределенной системы, и если отказоустойчивость раздела не может быть обеспечена, использование распределенной системы будет бессмысленным.
Кроме того, доступность особенно важна для бизнес-систем. Сегодня, когда много говорят о пользовательском опыте, если бизнес-система часто имеет «системные аномалии» и время отклика слишком велико, это значительно снизит благосклонность пользователя к системе.В сегодняшней жесткой конкуренции в интернет-индустрии , конкурентов в той же сфере не будет Даже перечислять, периодическая недоступность системы может сразу вызвать переток пользователей к конкурентам. Следовательно, мы можем пожертвовать согласованностью только в обмен на функциональность системы.ДоступностьиДопуск перегородки. Это БАЗОВАЯ теория, которая будет представлена ниже.
БАЗОВАЯ теория
Теория CAP говорит нам грустный, но вынужденный принять тот факт, что мы можем выбрать только два условия среди C, A, P. Для бизнес-систем мы часто жертвуем согласованностью в обмен на доступность системы и отказоустойчивость разделов. Однако здесь следует указать, что так называемая «жертва непротиворечивостью» заключается не в том, чтобы полностью отказаться от непротиворечивости данных, а в том, чтобы пожертвоватьсильная консистенцияобменслабая консистенция. Познакомимся с теорией BASE.
- BA: базовый доступный
- Вся система по-прежнему может гарантировать «доступность» при определенных форс-мажорных обстоятельствах, то есть по-прежнему может возвращать определенный результат в течение определенного периода времени. Просто разница между «в основном доступными» и «высокодоступными» заключается в следующем:
- «Определенный период времени» может быть соответствующим образом продлен Когда проводится большая акция, время отклика может быть соответственно увеличено.
- Вернуть страницу понижения версии некоторым пользователям Непосредственно верните страницу понижения версии некоторым пользователям, чтобы уменьшить нагрузку на сервер. Обратите внимание, однако, что возврат на страницу с пониженной версией по-прежнему возвращает явный результат.
- Вся система по-прежнему может гарантировать «доступность» при определенных форс-мажорных обстоятельствах, то есть по-прежнему может возвращать определенный результат в течение определенного периода времени. Просто разница между «в основном доступными» и «высокодоступными» заключается в следующем:
- S: Мягкое состояние: Мягкое состояние Состояние разных копий одних и тех же данных может не обязательно быть согласованным в реальном времени.
- E: Возможная согласованность: Возможная согласованность Статус разных копий одних и тех же данных может не обязательно быть согласованным в режиме реального времени, но должна быть гарантирована его согласованность по истечении определенного периода времени.
баланс pH
ACID может гарантировать сильную согласованность транзакций, то есть данные непротиворечивы в режиме реального времени. В локальных транзакциях это не проблема, в распределенных транзакциях строгая согласованность сильно повлияет на производительность распределенных систем, поэтому теорию BASE можно использовать в распределенных системах. Однако разные бизнес-сценарии распределенных систем предъявляют разные требования к согласованности. Например, в сценарии транзакции требуется строгая согласованность. В этом случае необходимо следовать теории ACID. В таких сценариях, как отправка кода подтверждения SMS после успешной регистрации, согласованность в реальном времени не требуется, поэтому можно следовать теории BASE. . Поэтому необходимо искать баланс между ACID и BASE согласно конкретным бизнес-сценариям.
Протокол распределенных транзакций
Несколько протоколов для реализации распределенных транзакций описаны ниже.
Протокол двухфазной фиксации 2PC
Трудность в распределенных системах заключается в том, как обеспечить согласованность нескольких узлов в архитектуре при выполнении транзакционных операций. Для достижения этого алгоритм двухэтапной фиксации основан на следующих предположениях:
- В этой распределенной системе есть один узел в качестве координатора (координатора), а другие узлы в качестве участников (когорты). И сетевое общение возможно между узлами.
- Все узлы используют журналы с упреждающей записью, а журнал хранится на надежном устройстве хранения после записи, даже если узел поврежден, данные журнала не исчезнут.
- Все узлы не повреждены навсегда и могут быть восстановлены даже после повреждения.
1. Первый этап (этап голосования):
- Узел-координатор запрашивает у всех узлов-участников возможность выполнения операции фиксации (голосования) и начинает ждать ответов от каждого узла-участника.
- Узел-участник выполняет все операции с транзакциями до тех пор, пока запрос не будет инициирован, и записывает информацию об отмене и повторении в журнал. (Примечание: в случае успеха каждый участник уже выполнил транзакционную операцию)
- Каждый узел-участник отвечает на запрос, инициированный узлом-координатором. Если транзакционная операция узла-участника действительно успешна, он возвращает сообщение «согласовано»; если транзакционная операция узла-участника фактически терпит неудачу, он возвращает сообщение «отмена».
2. Второй этап (стадия выполнения фиксации):
Когда соответствующие сообщения, полученные узлом-координатором от всех узлов-участников, «согласны»:
- Узел-координатор отправляет запрос «формальной фиксации» всем узлам-участникам.
- Узел-участник официально завершает операцию и освобождает ресурсы, занятые в течение всего периода транзакции.
- Узел-участник отправляет сообщение «выполнено» узлу-координатору.
- Узел-координатор завершает транзакцию после получения сообщения «готово» от всех узлов-участников.
Если ответное сообщение, возвращенное каким-либо узлом-участником на первом этапе, имеет значение «Прервано» или узел-координатор не может получить ответное сообщение от всех узлов-участников до истечения времени ожидания запроса на первом этапе:
- Узел-координатор отправляет запрос «отката» всем узлам-участникам.
- Узел-участник использует ранее записанную информацию об отмене для выполнения отката и освобождения ресурсов, занятых в течение всей транзакции.
- Узел-участник отправляет сообщение «откат завершен» узлу-координатору.
- Узел-координатор отменяет транзакцию после получения сообщения «откат завершен» от всех узлов-участников.
Независимо от конечного результата, вторая фаза завершает текущую транзакцию.
Двухфазная фиксация, кажется, обеспечивает атомарные операции, но, к сожалению, двухфазная фиксация имеет несколько недостатков:
- Во время выполнения все участвующие узлы блокируют транзакции. Когда участник занимает общедоступный ресурс, другие сторонние узлы должны находиться в состоянии блокировки для доступа к общедоступному ресурсу.
- Участник терпит неудачу. Координатору необходимо указать дополнительный механизм тайм-аута для каждого участника, после которого вся транзакция завершается сбоем. (Не большая отказоустойчивость)
- Координатор не работает. Участник будет заблокирован навсегда. Для отказоустойчивости требуются дополнительные резервные машины. (Это может полагаться на протокол Paxos, который будет описан позже, для реализации HA)
- Проблема, которую нельзя решить на втором этапе: координатор вылетает после отправки сообщения коммита, и единственный участник, получивший это сообщение, тоже вылетает в это же время. Тогда, даже если координатор создаст нового координатора через протокол выборов, состояние этой транзакции будет неопределенным, и никто не знает, была ли совершена транзакция.
С этой целью Дейл Скин и Майкл Стоунбрейкер предложили протокол трехэтапной фиксации (3PC) в «Формальной модели восстановления после сбоев в распределенной системе».
Протокол трехфазной фиксации 3PC
В отличие от двухфазной фиксации, трехфазная фиксация имеет две точки изменения.
- Внедрить механизм тайм-аута. При этом как у координатора, так и у участников вводится механизм тайм-аута.
- Вставьте этап подготовки между первым и вторым этапом. Гарантируется, что состояние каждого участвующего узла непротиворечиво перед финальной фазой фиксации.
То есть, в дополнение к введению механизма тайм-аута, 3PC снова делит этап подготовки 2PC на два, так что трехэтапная отправка имеет три этапа: CanCommit, PreCommit и DoCommit.
1. Стадия подтверждения
Фаза CanCommit в 3PC на самом деле очень похожа на фазу подготовки в 2PC. Координатор отправляет участнику запрос на фиксацию, и участник возвращает ответ «Да», если участник может отправить, в противном случае возвращает ответ «Нет».
- бизнес-запрос Координатор отправляет участнику запрос CanCommit. Спросите, можно ли выполнить операцию фиксации транзакции. Затем начните ждать ответа участника.
- Ответить на отзыв После того, как участник получит запрос CanCommit, при нормальных обстоятельствах, если он считает, что транзакция может быть успешно выполнена, он вернет ответ «Да» и перейдет в состояние готовности. В противном случае отзыв Нет
2. Предкоммитный этап
Координатор решает, можно ли запомнить операцию PreCommit транзакции в соответствии с реакцией участников. В зависимости от ответа возможны следующие две возможности. Если координатор получает ответ Да от всех участников, то выполняется предварительное выполнение транзакции.
-
Отправьте предварительный запрос Координатор отправляет участнику запрос PreCommit и переходит в фазу «Подготовлено».
-
Предварительная фиксация транзакции После того, как участник получит запрос PreCommit, операция транзакции будет выполнена, а информация об отмене и повторении будет записана в журнал транзакций.
-
Ответить на отзыв Если участник успешно выполняет транзакционную операцию, он возвращает ответ ACK и начинает ждать финальной команды.
Если какой-либо участник отправляет координатору ответ No или после ожидания таймаута координатор не получает ответа от участника, то транзакция прерывается.
-
отправить запрос на прерывание Координатор отправляет всем участникам запрос на прерывание.
-
прервать транзакцию После того, как участник получает от координатора запрос на прерывание (или по истечении тайм-аута запрос от координатора не получен), исполнение транзакции прерывается.
3. этап выполненияНа этом этапе выполняется отправка реальной транзакции, которую также можно разделить на следующие две ситуации.
На этом этапе выполняется отправка реальной транзакции, которую также можно разделить на следующие две ситуации.
3.1 Выполнение коммита
- отправить запрос на отправку Когда координатор получает ответ ACK, отправленный участником, он переходит из состояния предварительной фиксации в состояние фиксации. и отправить запрос на выполнение всем участникам.
- фиксация транзакции После того, как участник получает запрос doCommit, выполняется формальная фиксация транзакции. И освободите все ресурсы транзакции после завершения транзакции.
- Ответить на отзыв После фиксации транзакции координатору отправляется ответ Ack.
- завершить транзакцию После того, как координатор получит ответы подтверждения от всех участников, транзакция завершается.
3.2 Прерывание транзакцииЕсли координатор не получает ответ ACK, отправленный участником (может случиться так, что получатель не отправляет ответ ACK, или время ответа истекло), будет выполнена транзакция прерывания.
-
отправить запрос на прерывание Координатор отправляет всем участникам запрос на прерывание.
-
откат транзакции После получения запроса на прерывание участник использует информацию об отмене, записанную на этапе 2, для выполнения операции отката транзакции и освобождает все ресурсы транзакции после завершения отката.
-
результаты обратной связи После того, как участник завершает откат транзакции, он отправляет ACK-сообщение координатору
-
прервать транзакцию После того, как координатор получает сообщение ACK, возвращенное участником, транзакция прерывается.
Решения для распределенных транзакций
Решения для распределенных транзакций следующие:
- глобальное сообщение
- Распределенная транзакция на основе надежной службы сообщений
- TCC
- уведомление о лучших усилиях
Сценарий 1. Глобальная транзакция (модель DTP)
Глобальные транзакции реализованы на основе модели DTP. DTP — это модель распределенных транзакций, предложенная организацией X/Open — эталонная модель обработки распределенных транзакций X/Open. В нем указано, что для реализации распределенных транзакций требуются три роли:
-
AP: система приложений приложений Это бизнес-система, которую мы разработали.Во время нашей разработки мы можем использовать интерфейс транзакций, предоставленный менеджером ресурсов, для реализации распределенных транзакций.
-
ТМ: Менеджер транзакций Менеджер транзакций
- Реализация распределенных транзакций завершается диспетчером транзакций, который предоставляет интерфейс управления распределенными транзакциями для вызова нашей бизнес-системы. Эти интерфейсы называются интерфейсами TX.
- Диспетчер транзакций также управляет всеми диспетчерами ресурсов и отправляет эти диспетчеры ресурсов через предоставляемый ими интерфейс XA для реализации распределенных транзакций.
- DTP — это просто набор спецификаций для реализации распределенных транзакций, и он не определяет, как реализовать распределенные транзакции.TM может реализовывать распределенные транзакции с использованием таких протоколов, как 2PC, 3PC и Paxos.
-
RM: Менеджер ресурсов Менеджер ресурсов
- Объекты, которые могут предоставлять службы данных, могут быть менеджерами ресурсов, такими как базы данных, ПО промежуточного слоя для сообщений, кэши и т. д. В большинстве сценариев база данных является диспетчером ресурсов в распределенных транзакциях.
- Диспетчер ресурсов может обеспечить транзакционные возможности отдельной базы данных, а также возможности фиксации и отката базы данных через интерфейс XA, чтобы помочь диспетчеру транзакций реализовать распределенное управление транзакциями.
- XA — это интерфейс, определяемый моделью DTP, который используется для предоставления диспетчеру транзакций возможностей диспетчера ресурсов (базы данных) для фиксации, отката и т. д.
- DTP — это просто набор спецификаций для реализации распределенных транзакций, а конкретная реализация RM осуществляется поставщиками баз данных.
- Существует ли промежуточное ПО для распределенных транзакций на основе модели DTP?
- Каковы преимущества и недостатки модели DTP?
Вариант 2: распределенная транзакция на основе надежной службы сообщений
Этот способ реализации распределенных транзакций должен быть реализован через промежуточное программное обеспечение сообщений. Предположим, что есть две системы, A и B, которые могут обрабатывать задачи A и B соответственно. В это время в системе А есть бизнес-процесс, и задача А и задача Б должны быть обработаны в одной и той же транзакции. Давайте представим реализацию этой распределенной транзакции на основе промежуточного программного обеспечения сообщений.
- Прежде чем система A обработает задачу A, она сначала отправляет сообщение промежуточному программному обеспечению сообщений.
- ПО промежуточного слоя сообщений сохраняет сообщение после его получения, но не доставляет его. В это время нижестоящая система B еще не знает о существовании сообщения.
- После того, как промежуточное программное обеспечение сообщения успешно сохраняется, оно возвращает подтверждающий ответ системе А;
- После того, как система A получит ответ с подтверждением, она может начать обработку задачи A;
- После того, как задача A обработана, запрос Commit отправляется промежуточному программному обеспечению сообщений. После отправки запроса для системы А обработка транзакции завершена, и теперь она может обрабатывать другие задачи. Однако сообщение фиксации может быть потеряно во время передачи, поэтому промежуточное программное обеспечение сообщений не доставит сообщение в систему B, и система будет несогласованной. Эта проблема решается механизмом просмотра транзакций промежуточного программного обеспечения сообщений, который будет представлен ниже.
- После того, как промежуточное программное обеспечение сообщений получает команду Commit, оно доставляет сообщение системе B, тем самым инициируя выполнение задачи B;
- Когда задача B завершена, система B возвращает промежуточному программному обеспечению сообщения подтверждающий ответ, сообщая промежуточному программному обеспечению сообщений, что сообщение было успешно обработано.В это время распределенная транзакция завершена.
Из вышеописанного процесса можно сделать следующие выводы:
- Промежуточное программное обеспечение сообщений играет роль координатора распределенных транзакций.
- После того, как система А завершит задачу А, будет определенная разница во времени между выполнением задачи Б. В течение этой разницы во времени вся система находится в состоянии несогласованности данных, но эта кратковременная несогласованность допустима, поскольку через короткий промежуток времени система может снова поддерживать непротиворечивость данных, что удовлетворяет теории BASE.
В приведенном выше процессе, если обработка задачи А завершается сбоем, она должна войти в процесс отката, как показано на следующем рисунке:
- Если системе А не удастся обработать задачу А, она отправит запрос на откат промежуточному программному обеспечению сообщений. Как и при отправке запроса на фиксацию, после того, как система А отправила его, она может считать, что откат выполнен, и может заниматься другими делами.
- После получения запроса на откат ПО промежуточного слоя сообщений напрямую отбрасывает сообщение, не доставляя его системе Б, поэтому задача Б системы Б не будет запущена.
В этот момент система снова находится в согласованном состоянии, потому что ни задача A, ни задача B не выполняются.
И Commit, и Rollback, описанные выше, идеальны, но в реальных системах обе команды Commit и Rollback могут быть потеряны во время передачи. Итак, когда это происходит, как ПО промежуточного слоя сообщений обеспечивает согласованность данных? - Ответ заключается в механизме запроса тайм-аута.
В дополнение к реализации обычного бизнес-процесса, система А также должна предоставить интерфейс для запроса транзакций для вызова промежуточного программного обеспечения сообщений. Когда промежуточное программное обеспечение сообщений получает транзакционное сообщение, оно начинает отсчет времени.Если оно не получает команды фиксации или отката от системы А в течение периода ожидания, оно будет активно вызывать интерфейс запроса транзакции, предоставленный системой А, чтобы узнать о текущем состоянии система. . Интерфейс возвращает три результата:
- Отправить Если получен статус «зафиксировано», сообщение доставляется в систему B.
- откат Если получен статус «откат», сообщение сразу отбрасывается.
- Обработка Если получен статус «в обработке», продолжайте ждать.
Механизм запроса тайм-аута промежуточного программного обеспечения сообщений может предотвратить несогласованность системы, вызванную потерей команд фиксации/отката в вышестоящей системе во время передачи, а также может сократить время блокировки вышестоящей системы.Вышестоящая система может обрабатывать другие системы до тех пор, пока при выполнении команды Commit/Rollback, не дожидаясь подтверждения. Потеря команд Commit/Rollback компенсируется механизмом запроса тайм-аута, который значительно сокращает время блокировки вышестоящей системы и улучшает параллелизм системы.
Поговорим о гарантии надежности процесса доставки сообщения. Когда вышестоящая система завершает задачу и отправляет команду Commit промежуточному программному обеспечению сообщения, она может обрабатывать другие задачи.В это время она может считать, что транзакция была завершена, а затем промежуточное программное обеспечение сообщения должно убедиться, что сообщение успешно использовано. нижестоящей системой. ! ** Так как же это делается? Это гарантируется процессом доставки промежуточного программного обеспечения сообщений.
После того, как промежуточное программное обеспечение сообщений доставляет сообщение нижестоящей системе, оно переходит в состояние ожидания блокировки, нижестоящая система немедленно обрабатывает задачу и возвращает ответ промежуточному программному обеспечению сообщений после обработки задачи. После того, как промежуточное программное обеспечение сообщений получает ответ с подтверждением, оно считает, что транзакция завершена!
Если сообщение потеряно во время процесса доставки или ответ подтверждения сообщения потерян на обратном пути, промежуточное программное обеспечение сообщения будет повторно доставлено после ожидания тайм-аута ответа подтверждения, пока нижестоящий потребитель не вернет успешный ответ потребления. Конечно, общее промежуточное ПО для сообщений может устанавливать количество и временной интервал повторных попыток сообщения.Например, если первая доставка не удалась, оно будет повторять попытку каждые пять минут, всего 3 попытки. Если доставка не удалась после 3 попыток, сообщение требует ручного вмешательства.
Некоторые учащиеся могут спросить: почему бы вам не откатить сообщение после того, как его доставка не удалась, а продолжать пытаться доставить его повторно?
Это включает в себя стоимость реализации всей системы распределенных транзакций. Мы знаем, что когда система A отправит команду Commit промежуточному программному обеспечению сообщений, она будет делать другие вещи. Если в это время доставка сообщения не удалась и ее нужно откатить, системе А необходимо заранее предоставить интерфейс отката, что, несомненно, увеличит дополнительные затраты на разработку и усложнит бизнес-систему. Целью проектирования бизнес-системы является минимизация сложности системы при условии обеспечения производительности, чтобы снизить затраты на эксплуатацию и обслуживание системы.
Я не знаю, обнаружили ли вы, что вышестоящая система A отправляет сообщение Commit/Rollback промежуточному программному обеспечению сообщения асинхронным способом, то есть, когда вышестоящая система отправляет сообщение, она может делать другие вещи, а затем отправлять и rollback полностью передаются промежуточному программному обеспечению сообщений для завершения и полностью доверяют промежуточному программному обеспечению сообщений, что оно должно быть в состоянии правильно завершить фиксацию или откат транзакции. Однако процесс доставки сообщений нижестоящим системам с помощью ПО промежуточного слоя сообщений является синхронным. То есть после того, как промежуточное программное обеспечение сообщений доставляет сообщение нижестоящей системе, оно блокируется и ждет, пока нижестоящая система успешно обработает задачу и вернет подтверждение, прежде чем отменить ожидание блокировки. Почему они несовместимы по дизайну?
Прежде всего, асинхронная связь используется между вышестоящей системой и промежуточным программным обеспечением сообщений для улучшения параллелизма системы. Бизнес-система имеет дело непосредственно с пользователями, и пользовательский опыт особенно важен, поэтому этот асинхронный метод связи может значительно сократить время ожидания пользователей. Кроме того, по сравнению с синхронной связью, асинхронная связь не требует длительного ожидания блокировки, поэтому параллелизм системы также значительно увеличивается. Однако асинхронная связь может привести к потере команд фиксации/отката, что компенсируется механизмом запроса тайм-аута промежуточного программного обеспечения сообщений.
Итак, зачем использовать синхронную связь между промежуточным программным обеспечением сообщений и нижестоящими системами?
Асинхронность может улучшить производительность системы, но увеличит ее сложность, тогда как синхронизация снижает параллелизм системы, но стоимость реализации ниже. Поэтому, когда требования к параллелизму не очень высоки или когда ресурсов сервера относительно много, мы можем выбрать синхронизацию, чтобы уменьшить сложность системы. Мы знаем, что промежуточное программное обеспечение сообщений является сторонним промежуточным программным обеспечением, независимым от бизнес-системы. Оно не связано напрямую с какой-либо бизнес-системой и напрямую не связано с пользователями. Обычно оно развернуто на независимом кластере серверов и имеет хорошую масштабируемость, поэтому не слишком беспокойтесь о его производительности.Если скорость обработки не может удовлетворить наши требования, вы можете увеличить машину, чтобы решить эту проблему. Более того, даже если есть определенная задержка в скорости обработки промежуточного программного обеспечения сообщений, это приемлемо, потому что представленная ранее теория BASE говорит нам, что мы стремимся к согласованности в конечном счете, а не согласованности в реальном времени, поэтому промежуточное программное обеспечение сообщений генерирует это. допустимо, чтобы задержка вызывала временные несоответствия в транзакциях.
Сценарий 3. Уведомление о максимальных усилиях (регулярно проверяется)
Оповещение о лучших усилиях, также известное как регулярная корректура, фактически уже включено в схему 2. Здесь оно будет введено отдельно, в основном для целостности системы знаний. Это решение также требует участия промежуточного программного обеспечения сообщений, и процесс выглядит следующим образом:
- После того, как вышестоящая система завершает задачу, она синхронно отправляет сообщение промежуточному программному обеспечению сообщений, чтобы убедиться, что промежуточное программное обеспечение сообщений успешно сохраняет сообщение, а затем вышестоящая система может выполнять другие действия;
- После получения сообщения промежуточное программное обеспечение сообщений отвечает за синхронную доставку сообщения в соответствующую нижестоящую систему и запуск выполнения задачи нижестоящей системы;
- Когда нижестоящая система обрабатывает успешно, она отправляет ответ с подтверждением промежуточному программному обеспечению сообщений, и промежуточное программное обеспечение сообщений может удалить сообщение, тем самым завершив транзакцию.
Вышеупомянутый процесс является идеализированным, но в реальных сценариях часто возникают следующие непредвиденные ситуации:
- Промежуточному программному обеспечению сообщений не удалось доставить сообщение в нижестоящую систему.
- Системе восходящего потока не удалось отправить сообщение промежуточному программному обеспечению сообщений.
В первом случае промежуточное программное обеспечение сообщений имеет механизм повторных попыток. Мы можем установить количество повторных попыток сообщения и интервал времени повтора в промежуточном программном обеспечении сообщений. В случае сбоя доставки сообщения, вызванного нестабильностью сети, он часто повторяется несколько раз. После Это означает, что сообщение может быть успешно доставлено. Если доставка не удалась за пределами верхнего предела повторных попыток, промежуточное программное обеспечение сообщений больше не будет доставлять сообщение, но будет записано в таблицу сообщений об ошибках. Промежуточное программное обеспечение сообщений должно предоставлять интерфейс запроса для сообщения об ошибках Сообщения об ошибках нижестоящей системы периодически запрашиваются и используются, что называется «периодической корректурой».
Если повторная доставка и регулярная корректура не решают проблему, часто это происходит из-за серьезной ошибки в нижестоящей системе, которая требует ручного вмешательства.
Во втором случае необходимо установить механизм повторной передачи сообщений в вышестоящей системе. В вышестоящей системе может быть установлена локальная таблица сообщений, иобработка задачииВставить сообщение в локальную таблицу сообщенийЭти два шага выполняются в локальной транзакции. Если вставка сообщения в локальную таблицу сообщений не удалась, будет запущен откат, и предыдущий результат обработки задачи будет отменен. Если все эти шаги выполнены успешно, то локальная транзакция завершена. Затем будет выделенный отправитель сообщений для непрерывной отправки сообщений в локальную таблицу сообщений, и если отправка завершится неудачно, он вернется к повторной попытке. Конечно, также необходимо установить верхний предел повторных попыток для отправителя сообщения.Вообще говоря, если предел повторных попыток достигнут, а отправка все еще не удалась, это означает, что существует серьезная проблема с промежуточным программным обеспечением сообщения.В настоящее время, только ручное вмешательство может решить проблему.
Для программного обеспечения промежуточного слоя сообщений, которое не поддерживает транзакционные сообщения, если вы хотите реализовать распределенные транзакции, вы можете использовать этот метод. это может пройтимеханизм повторной попытки+Регулярная корректураРеализация распределенных транзакций, но по сравнению со второй схемой, для достижения согласованности данных требуется много времени, а также необходимо реализовать механизм публикации повторных попыток сообщения в вышестоящей системе, чтобы гарантировать, что сообщение будет успешно опубликовано в промежуточном программном обеспечении сообщений, которое несомненно, стоимость разработки бизнес-системы увеличивается, что делает бизнес-систему менее чистой, и эта дополнительная бизнес-логика, несомненно, будет занимать аппаратные ресурсы бизнес-системы, тем самым влияя на производительность.
Поэтому попробуйте выбрать ПО промежуточного слоя для сообщений, которое поддерживает транзакционные сообщения для реализации распределенных транзакций, например RocketMQ.
Схема 4: TCC (двухступенчатый, компенсационный)
TCC — это Try Confirm Cancel, компенсирующая распределенная транзакция. Как следует из названия, TCC реализует распределенные транзакции в три этапа:
- Попробуйте: попробуйте дело, которое нужно выполнить
- Этот процесс не выполняет бизнес, а просто завершает проверку согласованности всех бизнесов и резервирует все ресурсы, необходимые для выполнения.
- Подтвердить: выполнить бизнес
- Этот процесс фактически начинает выполнять бизнес.Поскольку проверка непротиворечивости была завершена на фазе «Попытка», этот процесс выполняется напрямую без какой-либо проверки. А в процессе выполнения будут использоваться бизнес-ресурсы, зарезервированные на этапе Try.
- Отменить: отменить выполненное дело
- Если бизнес-выполнение терпит неудачу, оно переходит в фазу «Отмена», которая освобождает все занятые бизнес-ресурсы и откатывает операции, выполненные в фазе «Подтверждение».
Ниже приведен пример передачи, поясняющий процесс реализации распределенных транзакций TCC.
Предположим, что пользователь А использует баланс своей учетной записи для отправки красного конверта со 100 юанями пользователю Б, а система баланса и система красных конвертов являются двумя независимыми системами.
-
Try
- Создайте поток передачи и установите статус потока нав сделке
- Вычесть 100 юаней со счета пользователя А (зарезервированные бизнес-ресурсы)
- После того, как попытка будет успешной, она войдет в стадию подтверждения.
- Если в процессе Try произойдет какая-либо аномалия, он перейдет в стадию Cancel.
-
Confirm
- Добавьте 100 юаней на счет пользователя B в красном конверте.
- Установите статус потока натранзакция завершена
- Если в процессе подтверждения возникает какая-либо аномалия, он переходит в стадию отмены.
- Процесс Confirm выполняется успешно, после чего транзакция завершается.
-
Cancel
- Увеличьте счет пользователя А на 100 юаней
- Установите статус потока натранзакция не удалась
В традиционном механизме транзакций выполнение бизнес-логики и обработка транзакций выполняются разными компонентами на разных этапах: часть бизнес-логики обращается к ресурсам для реализации хранения данных, а ее обработка является обязанностью бизнес-системы; обработка транзакций часть координируется диспетчером ресурсов, реализующим управление транзакциями, и его обработкой занимается диспетчер транзакций. Между ними не так много взаимодействия, поэтому логика обработки транзакций традиционного менеджера транзакций должна фокусироваться только на фазе завершения транзакции (фиксация/откат), а не на фазе бизнес-исполнения.
Глобальные транзакции TCC должны реализовывать глобальные транзакции на основе локальных транзакций RM.
Услуга TCC состоит из операций Try/Confirm/Cancel, Когда его служба Try/Confirm/Cancel выполняется, он обращается к диспетчеру ресурсов (далее именуемый RM) для доступа к данным. Эти операции доступа должны участвовать в локальной транзакции RM, так что измененные данные либо фиксируются, либо откатываются.
Это не сложно понять, рассмотрим следующий сценарий:
Если предположить, что служба B на рисунке не основана на локальных транзакциях RM (взяв в качестве примера RDBS, ее можно смоделировать, установив для автоматической фиксации значение true), то после сбоя операции [B:Try] в середине выполнение, структура транзакций TCC впоследствии решает откатить глобальную транзакцию, [B:Cancel] необходимо определить, какие операции в [B:Try] были записаны в БД, а какие не были записаны в БД: что бизнес [B:Try] имеет 5 операций записи в базу данных, бизнес [B:Cancel] ] должен определить, допустимы ли пять операций одну за другой, и выполнить обратную операцию для допустимых операций.
К сожалению, поскольку бизнес [B:Cancel] также имеет n (0
Напротив, для транзакций TCC, основанных на локальных транзакциях RM, с этой ситуацией легко справиться: операция [B:Try] не может быть выполнена в середине, и структура транзакций TCC может напрямую откатить свое участие в локальных транзакциях RM. Когда последующая структура транзакций TCC решает откатить глобальную транзакцию, зная, что «локальная транзакция RM, участвующая в операции [B:Try], была отменена», нет необходимости выполнять операцию [B:Cancel] вообще. .
Другими словами, когда структура транзакций TCC реализуется на основе локальных транзакций RM, операция отмены услуги типа TCC либо выполняется, либо не выполняется, и нет необходимости рассматривать частичное выполнение.
Структура транзакций TCC должна обеспечивать гарантию идемпотентности для службы подтверждения/отмены.
Обычно считается, что идемпотентность службы относится к нескольким (n>1) запросам к одной и той же службе и одному (n=1) запросу к ней, оба из которых имеют одинаковые побочные эффекты.
В модели транзакций TCC бизнес-подтверждение/отмена может вызываться неоднократно по многим причинам. Например, глобальная транзакция будет вызывать бизнес-логику подтверждения/отмены каждой службы TCC при фиксации/откате. При выполнении этих услуг подтверждения/отмены могут возникать сбои, такие как сбои в сети, что делает невозможным завершение глобальных транзакций. Следовательно, механизм восстановления после сбоя по-прежнему будет повторно отправлять/откатывать эти незавершенные глобальные транзакции в будущем, так что бизнес-логика подтверждения/отмены каждой службы TCC, участвующей в глобальной транзакции, будет вызываться снова.
Поскольку бизнес Confirm/Cancel может вызываться несколько раз, его идемпотентность должна быть гарантирована. Итак, гарантия идемпотентности должна быть предоставлена структурой транзакций TCC? Или бизнес-система должна сама обеспечивать идемпотентность? На мой взгляд, гарантия идемпотентности должна быть обеспечена структурой транзакций TCC. Если эта проблема возникает только у нескольких сервисов, то возможно, что виновата бизнес-система; однако это своего рода общественная проблема, и нет сомнений в том, что бизнес-подтверждение/отмена всех сервисов TCC имеет проблему идемпотентности. . Публичные проблемы сервисов ТСС должны решаться структурой транзакций ТСС, более того, учитывая вопросы, которые необходимо учитывать, когда бизнес-система ответственна за идемпотентность, будет обнаружено, что это, несомненно, увеличивает сложность бизнес-системы.
использованная литература
- Распределенная обработка транзакций в крупномасштабных системах SOA
- Жизнь за пределами распределенных транзакций: мнение отступника
- Небольшие размышления о том, как реализовать структуру распределенных транзакций TCC.
- How can a requestor ensure a consistent outcome across multiple, independent providers
- О распределенных транзакциях, двухфазном протоколе фиксации, трехфазном протоколе фиксации
- Three-phase commit protocol