Круто, спасибо :)… У нас топиков побольше будет, но это нюансы реализации (топик-на-тип события, типов сотни). У нас многие не рисуют, и так понятно. Те, кто рисует свой сложный кусочек, делает это примерно как и вы. Общая картинка в процессе, на ближайшем хайлоаде расскажу, как мы ее храним и визуализируем...
Общую единую базу изменений иметь удобно :)… А потом в ней же ещё делать транзакции ;)… Кончится может монолитом.
В нашей реализации, в PG Saga ( оркестра цинния) единая база +лог состояний на PostgreSQL. В этой статье единый лог состояний на шине (Кафка?). Т.е. элементы вашего подхода есть.
В чем риск- как бы не перегрузить единую базу состояний. Какой-то шаг положил туда много и часто, второй — начал читать это без индекса. И все, единая точка отказа складывает всю систему.
Про поддержку и развитие такой архитектуры: нелегко, как и с альтернативами :). На чем делается упор: единый реестр саг, где можно посмотреть текущие цепочки вызовов. При этом сами саги легкие, без сложной логики, без риска разрастания god object-ов. Сами сервисы, за счёт необходимости следовать общим правилам, тоже без избыточных зависимостей. Про команду, которая это делала: если команда одна, все это, возможно, вообще избыточно. Саги — это когда команд несколько, они независимо релизят, у них нет (обязательного ) общего планирования.
Про пример со снятием со счета и недоставленным сообщением — а что тут такого? Сбой на стороне смс- провайдера — не причина отменять отправку денег. Человек может сам глянуть свой баланс, можно отправить ему поясняющее письмо или push нотификацию. Смс может уйти через час. Это классический необязательный шаг, который никак не должен мешать завершению саги. Хорошая разница с транзакциями.
Тонкая тема :)… У копий сервиса должна быть общая база… Но масштабируемая, в идеале — шардируемая… Хотя довольно часто общего постгреса им всем хватает с 10 кратным
Совершенно верно, необходимость целостности чаще все рождается там, где затрагиваются деньги. В нашем случае — когда в процессе хоть где-то есть биллинг (аренда, доставка, покупка услуг, покупка отчётов).
Паттерн с финансовым ACID монолитом в центре (кейс банков и, внезапно, убера) — это понятно, привычно… но немного старомодно и немасштабируемо. Старая проверенная временем классика, но не критерий оценки новых решений.
Про решения задачи: я, в контексте саг, строго за вариант 3. Чтобы в сервисы шли не не директивные апдейты "сумма на счету стала X (т.к. было Y а я вычел Z и налоги, но это мое дело)", а бизнесовые запросы "поступило X денег", "отправь Y денег"… В случае которых с линеаризуемостью проще
Никакой линеаризуемости тут не предполагается, совершенно верно. Я пытался на это указать, когда выкидывал I из ACID.
Предлагаю вам (и другим комментаторам выше предложу) простую игру: опишите бизнес сценарий в микросервисной архитектуре, где отсутствие линеаризуемости приводит к ошибкам. А я постараюсь его положить на саги. Не факт что получится, но вдруг :)… Гипотеза: линеаризуемость не нужна самому бизнес процессу, она нужна разработчику, т.к. нашему мозгу проще осознавать линеаризуемые процессы.
Рассматривались все шины. Кролик не попал в шорт-лист из-за сложностей с поддержкой кросс-датацентрового развертывания. У нас он исторически много где был, но все чаще просят "только не кролик"
Да, терминологически термин «оптимистичный» я использовал не совсем правильно. В статье 2017 он касается прежде всего OCC, алгоритма с оптимистичным коммитом. Тут возникла сложность из-за упаковки результатов из нескольких статей в один абзац. В том числе, многие идеи были взяты, например, из The Homeostasis Protocol: Avoiding Transaction Coordination Through Program Analysis, и упомянутых в статье 2017 года детерменистических алгоритмов, которые минимизируют постфактум координацию за счет анализа кода при выполнении. Я их всех скопом обозвал оптимистичными, в плане координации.
Кто касается синхронизации на атомарном действии — в целом это верно, с точки зрения невозможности выполнения одновременных изменений на, например, одном пользователе. Но даже порядок выполнения действий над одним пользователем в ходе работы разных саг, в общем случае, не гарантирован. Если саги стартуют одновременно, нельзя быть точно уверенным, какая первая доберется до пользователя.
Про набор костылей — возможно так и есть. Механически переложить старую монолитную логику, без переписывания сервисов согласно Domain Driven Desighn и Single Point of Responsibility, у нас не получается.
Возможно, у вас получится :)… Статью прочитал, было интересно. СРазу возник вопрос — как система обрабатывает ситуацию, когда одна полу-транзакция отработала, закоммитилась, передала управление на вторую, а потом отразившая первую полутранзакцию база была утерена и восстановлена без следов этой полутранзакции?
Самое опасное последствие этой статьи — это представление, что с помощью саг можно дешево сделать распределенные транзакции. Это не так, логику основанную на распределенных транзакциях нельзя переносить на саги as is. Речь про другой подход к проектированию логики, БЕЗ распределенных транзакций.
Как так ни слова? :))) Вот вы же их и написали. Я когда статью писал — обоими руками себя держал, чтобы уложиться во вменяемый объем и передать суть с определением минимума терминов.
Проверим :)… Кафку используют все, где тут инженерный челлендж? Про сбои — нарушение порядка на больших объемах это норм. А вот потеря — это будет приговор.
Статью почитаю, спасибо. Про оптимистичный подход — тут ключевая оптимистичность в полном отказе от коммита. Поэтому синхронизация не ситуативная, а вообще отсутствует.
Про целостность — тоже да, это в чистом виде eventual consistency.
Про риски откатов — есть такое. Мы внутри себя поняли, что эта схема будет работать, только если при разработке мы полностью уйдем от операций вида «обнови объявление и поставь статус X». Для отката таких штук очень важен порядок. Внутри саг безопасно использовать команды вида «произошло то-то и то-то», а сервис уже сам решает, какие поля ему обновлять, и что еще учесть. Никаких безусловных директив.
Зависимости — никак. Зачем?
Параллелизм шагов не является сутью описанного подхода. Описанный подход с последовательными шагами не станет распределенной транзакцией, ни в каком виде.
Да, «об опасности бытовых аналогий» :)))… Схему вида «продавщица пробивает на кассе товар, снятый с полки за спиной» нельзя масштабировать только кассами. Нужно масштабировать еще и продавщиц с полками и товаром. А ашан вполне масштабируется, в том числе, просто кассами, даже без продавщиц, это можно у них вживую наблюдать.
В тексте нет ни слова про распределенную транзакцию. Вообще не представляю, как возможны параллельные шаги распределенной транзакции.
Речь идет о подходе, альтернативном транзакциям. Соответственно, нельзя ссылаться на данные, измененные ранее. Т.к. в момент выполнения операции эти изменения уже могут быть отменены.
Круто, спасибо :)… У нас топиков побольше будет, но это нюансы реализации (топик-на-тип события, типов сотни). У нас многие не рисуют, и так понятно. Те, кто рисует свой сложный кусочек, делает это примерно как и вы. Общая картинка в процессе, на ближайшем хайлоаде расскажу, как мы ее храним и визуализируем...
Общую единую базу изменений иметь удобно :)… А потом в ней же ещё делать транзакции ;)… Кончится может монолитом.
В нашей реализации, в PG Saga ( оркестра цинния) единая база +лог состояний на PostgreSQL. В этой статье единый лог состояний на шине (Кафка?). Т.е. элементы вашего подхода есть.
В чем риск- как бы не перегрузить единую базу состояний. Какой-то шаг положил туда много и часто, второй — начал читать это без индекса. И все, единая точка отказа складывает всю систему.
Про поддержку и развитие такой архитектуры: нелегко, как и с альтернативами :). На чем делается упор: единый реестр саг, где можно посмотреть текущие цепочки вызовов. При этом сами саги легкие, без сложной логики, без риска разрастания god object-ов. Сами сервисы, за счёт необходимости следовать общим правилам, тоже без избыточных зависимостей. Про команду, которая это делала: если команда одна, все это, возможно, вообще избыточно. Саги — это когда команд несколько, они независимо релизят, у них нет (обязательного ) общего планирования.
Про пример со снятием со счета и недоставленным сообщением — а что тут такого? Сбой на стороне смс- провайдера — не причина отменять отправку денег. Человек может сам глянуть свой баланс, можно отправить ему поясняющее письмо или push нотификацию. Смс может уйти через час. Это классический необязательный шаг, который никак не должен мешать завершению саги. Хорошая разница с транзакциями.
Тонкая тема :)… У копий сервиса должна быть общая база… Но масштабируемая, в идеале — шардируемая… Хотя довольно часто общего постгреса им всем хватает с 10 кратным
Совершенно верно, необходимость целостности чаще все рождается там, где затрагиваются деньги. В нашем случае — когда в процессе хоть где-то есть биллинг (аренда, доставка, покупка услуг, покупка отчётов).
Паттерн с финансовым ACID монолитом в центре (кейс банков и, внезапно, убера) — это понятно, привычно… но немного старомодно и немасштабируемо. Старая проверенная временем классика, но не критерий оценки новых решений.
Про решения задачи: я, в контексте саг, строго за вариант 3. Чтобы в сервисы шли не не директивные апдейты "сумма на счету стала X (т.к. было Y а я вычел Z и налоги, но это мое дело)", а бизнесовые запросы "поступило X денег", "отправь Y денег"… В случае которых с линеаризуемостью проще
Никакой линеаризуемости тут не предполагается, совершенно верно. Я пытался на это указать, когда выкидывал I из ACID.
Предлагаю вам (и другим комментаторам выше предложу) простую игру: опишите бизнес сценарий в микросервисной архитектуре, где отсутствие линеаризуемости приводит к ошибкам. А я постараюсь его положить на саги. Не факт что получится, но вдруг :)… Гипотеза: линеаризуемость не нужна самому бизнес процессу, она нужна разработчику, т.к. нашему мозгу проще осознавать линеаризуемые процессы.
Мы 10 лет держались без распределенности, ростили монолит :)… Это не такое плохое решение, на самом
Опасно, да.
Рассматривались все шины. Кролик не попал в шорт-лист из-за сложностей с поддержкой кросс-датацентрового развертывания. У нас он исторически много где был, но все чаще просят "только не кролик"
О, супер, думаю, получится продолжить дискуссию :)
Кто касается синхронизации на атомарном действии — в целом это верно, с точки зрения невозможности выполнения одновременных изменений на, например, одном пользователе. Но даже порядок выполнения действий над одним пользователем в ходе работы разных саг, в общем случае, не гарантирован. Если саги стартуют одновременно, нельзя быть точно уверенным, какая первая доберется до пользователя.
Про набор костылей — возможно так и есть. Механически переложить старую монолитную логику, без переписывания сервисов согласно Domain Driven Desighn и Single Point of Responsibility, у нас не получается.
Возможно, у вас получится :)… Статью прочитал, было интересно. СРазу возник вопрос — как система обрабатывает ситуацию, когда одна полу-транзакция отработала, закоммитилась, передала управление на вторую, а потом отразившая первую полутранзакцию база была утерена и восстановлена без следов этой полутранзакции?
Самое опасное последствие этой статьи — это представление, что с помощью саг можно дешево сделать распределенные транзакции. Это не так, логику основанную на распределенных транзакциях нельзя переносить на саги as is. Речь про другой подход к проектированию логики, БЕЗ распределенных транзакций.
Как так ни слова? :))) Вот вы же их и написали. Я когда статью писал — обоими руками себя держал, чтобы уложиться во вменяемый объем и передать суть с определением минимума терминов.
Проверим :)… Кафку используют все, где тут инженерный челлендж? Про сбои — нарушение порядка на больших объемах это норм. А вот потеря — это будет приговор.
Про целостность — тоже да, это в чистом виде eventual consistency.
Про риски откатов — есть такое. Мы внутри себя поняли, что эта схема будет работать, только если при разработке мы полностью уйдем от операций вида «обнови объявление и поставь статус X». Для отката таких штук очень важен порядок. Внутри саг безопасно использовать команды вида «произошло то-то и то-то», а сервис уже сам решает, какие поля ему обновлять, и что еще учесть. Никаких безусловных директив.
Параллелизм шагов не является сутью описанного подхода. Описанный подход с последовательными шагами не станет распределенной транзакцией, ни в каком виде.
В тексте нет ни слова про распределенную транзакцию. Вообще не представляю, как возможны параллельные шаги распределенной транзакции.
Речь идет о подходе, альтернативном транзакциям. Соответственно, нельзя ссылаться на данные, измененные ранее. Т.к. в момент выполнения операции эти изменения уже могут быть отменены.
И NATS Streaming.
Обе шины в процессе нагрузочного тестирования сейчас.