Это безусловно верно, и было верно еще в рамках предыдущей парадигмы, managed баз и сервисов :)… Практически все западные стартапы живут в AWS или Azure, это уже данность, все привыкли.
В случае p2p сервер тоже, получается, есть, им является одна из клиентских машин :)… Или обе.
Здесь можно говорить об «эффективном» отсутствии сервера. Т.е. к серверу нельзя подключится по SSH, нельзя писать код в предположении, что под разными
функциями лежит общий диск, оперативка, или хоть что-то общее.
Например — другой язык, отдельный репозиторий, другая база (локальная для сервиса), свои кэши, свое масштабирование. Сервис на GoLang, прикрытый Тарантулом, все модной красивое, но для задач, требующих согласованности — открывается соединение с общим Постгресом и дергаются нужные хранимки.
ок — не в плане архитектурной чистоты, а в плане базовой работоспособности.
В этом подходе можно жить, можно развиваться, есть ряд преимуществ с чистым монолитом.
Видя чужие модели, можно заранее увидеть потенциальные поломки у соседей, а не узнать об этом постфактум.
Но изоляция… усложнена.
… мы зашли в область NDA и конфиденциальной информации :)…
Скажем так — скорее централизованная, мы верим людям… но очень любим автоматизацию всяких… безопасных штук.
Вот теперь понятнее стало.
Описанный в статье подход — про дополнение через сканирование и autodiscovery.
Т.к. экосистема Авито — это десятки кросфункциональных команд, маленьких стартапов, каждый из которых запускает/развивает/выводит сервисы независимо, сам выбирает и меняет бызы. И таких сервисов с базами много сотен, каждый день что-то меняется.
Было бы излишне самоуверенно считать, что я изобрел что-то действительно новое, о новом пишут не на хабре, а в рамках научной публикации :)
Описанное в статье — это не полностью новое, это творческое переосмысление различных инструментов, позволяющее им сосуществовать вместе.
Я бы скорее сказал, что Configuration Management Database и ServiceNow Workflows являются хорошими кандидатами на роль источника данных для определенных слоев.
Вот смешно получилось, неужели у меня фраза Polyglot Persistence ни разу в тексте не прозвучала?… проверил, похоже действительно нет.
Дело в том, что эта статья продолжает предыдущую, где эта фраза есть: habr.com/ru/company/avito/blog/426101
Базы микросервисов Авито строятся согласно Polyglot Persistence. По предыдущей статье можно понять, что среди этих баз есть и key-value, есть и document-based… чего там только нет. И помнящая ткань — это не про само хранение, а про структурирование метаданных о хранении.
Минимально я бы добавил инструмент отслеживания незавершённых цепочек, чтобы их зачищать. У вас уже сейчас есть элемент из немного другого мира: сервис-коопдинатор. В принципе он может взять на себя такую уборку. Или по крону проверку запускать.
Неминимально — шину для хореографической или базу состояний для оркестрационной саги. Единое отказоустойчивое помнящее пространство между сервисами.
В парадигме саг — строго асинхронно. Никого ждать нельзя, fire&forget. Для быстрого вызова (1-2ms) можно и REST, но дублирующую запись лучше все равно в шину бросить. Чтобы упавший сервис, даже без надёжной базы, смог воскреснуть и перепроиграть упущенные из-за сбоя операции. И аналитику вы на шине получите забесплптно.
4.про шину, мы выбираем между кафкой и nats streaming. У нас есть большой чек-лист, про него возможно потом расскажем, рэбит туда не проходит. Но это наш чек-лист, там огромные объемы, масштабирование, поддержка кросс-дц… Может вам кролик и норм. При этом, да сервис саг может реализовывать персистентную очередь и внутри. У нас в PG Saga так и есть. Но эта самодельная очередь не выдержит весь наш траффик, только финансовый. Поэтому мы и смотрим на большую шину.
5.конечно, ряд шагов саги не нуждаются в компенсациях, как в примере с емейлом… Ушло и ушло, что поделать. Тем меньше нагрузка.
6.event sourcing помогает. Про удаление — я вообще против удаления, только за маркирование записей… Конечно, иногда приходится, но чем меньше удалять, тем безопаснее.
7.про ux вообще сложно, я обычно на слой -два глубже работаю. Описанная вами схема, с моей точки зрения, на саге должна выглядеть так: ux форма дёргает координатора (сервис бизнес логики ), он стартует сагу, будучи шагом 0, и кидает в шину запись с введенными (и провалидированными) пользовательскими полями. На эту запись срабатывает шаг 1, SSO, кидает сообщение об успехе, на который срабатывает шаг 2. На успех шага 2 реагирует
снова координатор (шаг 3), который кидает в шину заявку на е-мейл, рисует ОК пользователю в UI и завершает сагу. Компенсации делают шаги 1 и 2, маркируя созданные учётки как убитые.
Конечно, для описанного сценария сага это немножко overkill, того же можно добиться кроном с проверками. Чтобы при сбое шага 1 или 2 созданные куски пользователя блокировались, а пользователь предупреждался емейлом. Саги тем более полезны, чем длиннее, сложнее сценарии, и чем больше их одновременно работает. Когда независимые команды вписывают в регистрацию начисление бонусных баллов, рассчет рейтингов, оповещение ещё и по смс… И все даунтайма основного процесса.
Про кванты — постараюсь через несколько месяца родить статью про квантовые вычисления. Не смотря на квантовую природу вычислений, ввод и вывод данных осуществляется через классические биты, недетерменированно и местами вообще статистически: запуск в идентичных начальных условиях в общих случаях не гарантирует идентичные результаты.
Информационную систему над реальным миром (над множеством квантовых объектов) я бы советовал рассаматривать аналогично — неполный детерменизм. Бизнес приложение, которое работает ОК в 99.9% случаев, можно считать супер успешным. А 0.1% тех, кому не повезло, можно десятикратный бонус выплатить.
Для этого не надо писать сервис...
Стоп-стоп, обращаю внимание на название статьи. Изолированные бизнес-сервисы первичны, часто вообще не делящие данные и сущности между друг другом. Все дело в том, что на первом шаге в двухфазном коммите ничего такого не происходит, а только блокируются записи. Т.е. такие операции неравноценны, а потому 2N может оказаться меньше N.
Вот тут я категорически не согласен. 2N = 4 похода по сети. Потенциальные точки сбоев и задержек коммуникации. Это первое.
На первом шаге в реальном, не теоретическом сценарии, проводится проверка бизнес-условий, а только потом блокировка. Первый шаг может легко быть дольше второго. И каждый шаг должен проходить в отдельной локальной транзакции (две транзакции), каждую из которых нужно открыть и закрыть. ... речь про теоретическую возможность...
Давайте лучше посмотрим практический пример. Отдельный сервис (доставки?), у его база на MongoDB. Для поддержки двухфазного коммита нужно уметь сущность (адрес доставки?) в два шага блокировать и разблокировать. В монге этот фокус надежно можно сделать либо через Update записи, либо через отдельную таблицу блокировок, которую нужно джойнить с таблицей сущностей.
Обе эти операции, по умолчанию, очень тяжелы для монги. Любой бизнес-сценарий аналогичной бизнес-сложности, построенный на атомарных записях+чтении единственной записи, будет в разы быстрее.
Я попрошу ребят сделать статью :)…
Думаю, в основном потому, что для работы с кроликом нужно решать проблемы, а новые модные шины, теоретически, должны работать автоматически из коробки.
Возможно, это иллюзия…
Заблуждение… https://en.m.wikipedia.org/wiki/No-teleportation_theorem
Состояние детерминировано, но квантовыми битами, его невозможно 100% точно закодировать классическими битами, булевыми. Всегда есть простор случайности, всегда недетерменизм.
Про двухфазный коммит (статью прочитал): он может и не тормозной. Но каждый сервис системы должен быть с нуля описан так, чтобы понимать двухфазные операции (prepare+commit). Даже если сервис на Go, а база у него на неконсистентной монге.
Что же касается сравнения с сагой по скорости: 2-х фазному комиту, как ясно по названию, всегда нужно 2N операций. А Саге — N для корректной саги, и 2m для сбоившей (m-номер сбоившего шага, от 1 до N).
Сага всегда будет быстрее. Вопрос в рисках нарушения целостности на Саге, которые я бы предложил обсуждать на практических примерах.
Вы описываете кейс предварительного избыточного шардирования. Мы его раньше часто применяли, например, в мессенджере. Это, по сути ручное шардирование единой базы, после которого решардировать уже нельзя, можно давать больше физических машин. 64 логических шардов базы, на 4 машинах (и 4 слева), а копий сервиса, внезапно… 7!… В кубе (Kubernetes). А вечером 9. А утром 3. При этом шаг с 64 логических шардов до 128 (у вас с 10 до 20) может быть адским.
Что касается копий сервиса, сейчас прогресс идёт в сторону гибкого решардировая. Предел этого процесса, уже достигнутый в облаке АлиЙунь — это функциональный подход, одноразовый микропод (копия сервиса) в облаке под каждый (!) вызов сервиса. Выделяется под вызов и потом гасится. Конечно, с базами так нельзя, база должна жить и шардироваться
Вот тут не соглашусь. Своя база у каждой копии блокирует масштабирование вверх или вниз. Было 3 копии сервисов, в пике понадобилось 10, а потом 2… Как дробить/сливать отдельные базы, да ещё и быстро, по ?
Отдельные саги в бою уже полгода. Их станет больше. И есть инсайт от других компаний, которые начали раньше и испытали больше.
Полного понимания нет :)… Понятно, что распределенные транзакции у нас не взлетят, как и микросервисы без саг. Но всех нюансов и опасностей мы ещё точно не испытали :)
Я бы сказал, что сагу можно назвать супер-оптимистичной транзакцией. :) В ту сторону, где оптимизм уже граничит с идиотизмом.
Это сознательный отход от контроля И 100% детерминизма, т.к. та же квантовая физика учит нас, что реальность не детерминирована. No teleportation theorem и все такое.
Про подход к идемпотентному восстановлению полутранзакций по логу(шине) — да, понял, у нас это предусмотрено примерно также.
Здесь можно говорить об «эффективном» отсутствии сервера. Т.е. к серверу нельзя подключится по SSH, нельзя писать код в предположении, что под разными
функциями лежит общий диск, оперативка, или хоть что-то общее.
В этом подходе можно жить, можно развиваться, есть ряд преимуществ с чистым монолитом.
Видя чужие модели, можно заранее увидеть потенциальные поломки у соседей, а не узнать об этом постфактум.
Но изоляция… усложнена.
Скажем так — скорее централизованная, мы верим людям… но очень любим автоматизацию всяких… безопасных штук.
Описанный в статье подход — про дополнение через сканирование и autodiscovery.
Т.к. экосистема Авито — это десятки кросфункциональных команд, маленьких стартапов, каждый из которых запускает/развивает/выводит сервисы независимо, сам выбирает и меняет бызы. И таких сервисов с базами много сотен, каждый день что-то меняется.
Описанное в статье — это не полностью новое, это творческое переосмысление различных инструментов, позволяющее им сосуществовать вместе.
Я бы скорее сказал, что Configuration Management Database и ServiceNow Workflows являются хорошими кандидатами на роль источника данных для определенных слоев.
Дело в том, что эта статья продолжает предыдущую, где эта фраза есть: habr.com/ru/company/avito/blog/426101
Базы микросервисов Авито строятся согласно Polyglot Persistence. По предыдущей статье можно понять, что среди этих баз есть и key-value, есть и document-based… чего там только нет. И помнящая ткань — это не про само хранение, а про структурирование метаданных о хранении.
4.про шину, мы выбираем между кафкой и nats streaming. У нас есть большой чек-лист, про него возможно потом расскажем, рэбит туда не проходит. Но это наш чек-лист, там огромные объемы, масштабирование, поддержка кросс-дц… Может вам кролик и норм. При этом, да сервис саг может реализовывать персистентную очередь и внутри. У нас в PG Saga так и есть. Но эта самодельная очередь не выдержит весь наш траффик, только финансовый. Поэтому мы и смотрим на большую шину.
5.конечно, ряд шагов саги не нуждаются в компенсациях, как в примере с емейлом… Ушло и ушло, что поделать. Тем меньше нагрузка.
6.event sourcing помогает. Про удаление — я вообще против удаления, только за маркирование записей… Конечно, иногда приходится, но чем меньше удалять, тем безопаснее.
7.про ux вообще сложно, я обычно на слой -два глубже работаю. Описанная вами схема, с моей точки зрения, на саге должна выглядеть так: ux форма дёргает координатора (сервис бизнес логики ), он стартует сагу, будучи шагом 0, и кидает в шину запись с введенными (и провалидированными) пользовательскими полями. На эту запись срабатывает шаг 1, SSO, кидает сообщение об успехе, на который срабатывает шаг 2. На успех шага 2 реагирует
снова координатор (шаг 3), который кидает в шину заявку на е-мейл, рисует ОК пользователю в UI и завершает сагу. Компенсации делают шаги 1 и 2, маркируя созданные учётки как убитые.
Конечно, для описанного сценария сага это немножко overkill, того же можно добиться кроном с проверками. Чтобы при сбое шага 1 или 2 созданные куски пользователя блокировались, а пользователь предупреждался емейлом. Саги тем более полезны, чем длиннее, сложнее сценарии, и чем больше их одновременно работает. Когда независимые команды вписывают в регистрацию начисление бонусных баллов, рассчет рейтингов, оповещение ещё и по смс… И все даунтайма основного процесса.
Информационную систему над реальным миром (над множеством квантовых объектов) я бы советовал рассаматривать аналогично — неполный детерменизм. Бизнес приложение, которое работает ОК в 99.9% случаев, можно считать супер успешным. А 0.1% тех, кому не повезло, можно десятикратный бонус выплатить.
Для этого не надо писать сервис...
Стоп-стоп, обращаю внимание на название статьи. Изолированные бизнес-сервисы первичны, часто вообще не делящие данные и сущности между друг другом.
Все дело в том, что на первом шаге в двухфазном коммите ничего такого не происходит, а только блокируются записи. Т.е. такие операции неравноценны, а потому 2N может оказаться меньше N.
Вот тут я категорически не согласен. 2N = 4 похода по сети. Потенциальные точки сбоев и задержек коммуникации. Это первое.
На первом шаге в реальном, не теоретическом сценарии, проводится проверка бизнес-условий, а только потом блокировка. Первый шаг может легко быть дольше второго. И каждый шаг должен проходить в отдельной локальной транзакции (две транзакции), каждую из которых нужно открыть и закрыть.
... речь про теоретическую возможность...
Давайте лучше посмотрим практический пример. Отдельный сервис (доставки?), у его база на MongoDB. Для поддержки двухфазного коммита нужно уметь сущность (адрес доставки?) в два шага блокировать и разблокировать. В монге этот фокус надежно можно сделать либо через Update записи, либо через отдельную таблицу блокировок, которую нужно джойнить с таблицей сущностей.
Обе эти операции, по умолчанию, очень тяжелы для монги. Любой бизнес-сценарий аналогичной бизнес-сложности, построенный на атомарных записях+чтении единственной записи, будет в разы быстрее.
Думаю, в основном потому, что для работы с кроликом нужно решать проблемы, а новые модные шины, теоретически, должны работать автоматически из коробки.
Возможно, это иллюзия…
Заблуждение… https://en.m.wikipedia.org/wiki/No-teleportation_theorem
Состояние детерминировано, но квантовыми битами, его невозможно 100% точно закодировать классическими битами, булевыми. Всегда есть простор случайности, всегда недетерменизм.
Про двухфазный коммит (статью прочитал): он может и не тормозной. Но каждый сервис системы должен быть с нуля описан так, чтобы понимать двухфазные операции (prepare+commit). Даже если сервис на Go, а база у него на неконсистентной монге.
Что же касается сравнения с сагой по скорости: 2-х фазному комиту, как ясно по названию, всегда нужно 2N операций. А Саге — N для корректной саги, и 2m для сбоившей (m-номер сбоившего шага, от 1 до N).
Сага всегда будет быстрее. Вопрос в рисках нарушения целостности на Саге, которые я бы предложил обсуждать на практических примерах.
Про графы ответ — графовая база :)… Будет доклад на ближайшем хайлоаде.
Про формат: https://m.habr.com/company/avito/blog/419651/ :)
Вы описываете кейс предварительного избыточного шардирования. Мы его раньше часто применяли, например, в мессенджере. Это, по сути ручное шардирование единой базы, после которого решардировать уже нельзя, можно давать больше физических машин. 64 логических шардов базы, на 4 машинах (и 4 слева), а копий сервиса, внезапно… 7!… В кубе (Kubernetes). А вечером 9. А утром 3. При этом шаг с 64 логических шардов до 128 (у вас с 10 до 20) может быть адским.
Что касается копий сервиса, сейчас прогресс идёт в сторону гибкого решардировая. Предел этого процесса, уже достигнутый в облаке АлиЙунь — это функциональный подход, одноразовый микропод (копия сервиса) в облаке под каждый (!) вызов сервиса. Выделяется под вызов и потом гасится. Конечно, с базами так нельзя, база должна жить и шардироваться
Отрезает последнее слово: по нажатию одной кнопки.
Вот тут не соглашусь. Своя база у каждой копии блокирует масштабирование вверх или вниз. Было 3 копии сервисов, в пике понадобилось 10, а потом 2… Как дробить/сливать отдельные базы, да ещё и быстро, по ?
Отдельные саги в бою уже полгода. Их станет больше. И есть инсайт от других компаний, которые начали раньше и испытали больше.
Полного понимания нет :)… Понятно, что распределенные транзакции у нас не взлетят, как и микросервисы без саг. Но всех нюансов и опасностей мы ещё точно не испытали :)
Я бы сказал, что сагу можно назвать супер-оптимистичной транзакцией. :) В ту сторону, где оптимизм уже граничит с идиотизмом.
Это сознательный отход от контроля И 100% детерминизма, т.к. та же квантовая физика учит нас, что реальность не детерминирована. No teleportation theorem и все такое.
Про подход к идемпотентному восстановлению полутранзакций по логу(шине) — да, понял, у нас это предусмотрено примерно также.