Взгляните на стратегии, думая о распределенных системах и микросервисах

Архитектура микросервисов может помочь командам разрабатывать приложения асинхронно. Команды могут развернуть свою базу кода, что в целом ускорит итерацию и процесс разработки. Однако с гибкостью возникает сложность в разработке распределенных систем. Многие из наших предположений в отношении единой системы не работают в распределенной системе, и нам необходимо пересмотреть свой подход к проектированию в распределенных системах.

Одним из примеров этого является упорядочение по времени. Недавно я задался вопросом, как обеспечить правильный порядок созданных вами сервисов.

Представьте, что вы создали управляемую событиями архитектуру с двумя микросервисами: сервисом продукта и сервисом заказа.

Служба продуктов будет отвечать за управление продуктами, а службы заказов надежны для управления заказами. Служба продукта может выдавать CreateEvent и UpdateEvent, и в зависимости от события служба заказа принимает сообщения через очередь и обновляет свое локальное хранилище данных.

Как вы гарантируете, что CreateEvent всегда может быть раньше UpdateEvent?

Одно из простых решений - попросить подписчика провести проверку. Если продукта A не существует, мы можем снова отправить значение в очередь, предполагая, что CreateEvent вышел из строя.

Однако, если подписчик получил два UpdateEvents на одном и том же продукте из строя, это вызовет проблему.

Мы могли бы подумать, что можем создать временную метку для каждого события, и на основе этой временной метки мы можем определить, нужно ли обновлять время. Однако этот подход тоже может быть неверным.

А как насчет времени?

Время имеет жизненно важное значение в распределенной системе не потому, что мы заботимся о времени, в которое происходит конкретное событие в системе, а о порядке, в котором это событие происходит. Благодаря нашему предположению время может помочь нам упорядочить вещи.

Поскольку время позволяет нам наблюдать за созданием и обновлением событий в хронологическом порядке, мы можем сказать, находится ли A до или после B.

Понятие времени и того, как оно работает в реальном мире, линейно. Причина в том, что мы живем в единой унифицированной системе, и все мы согласны с понятием часовых поясов и общих часов (UTC). Поэтому, когда мы спрашиваем, сколько времени в конкретном месте, редко возникают расхождения.

Более того, мы думаем, что события обычно происходят одно за другим. Например, событие A происходит до события B, если время события A раньше, чем время события B. В этом случае мы предполагаем, что точный порядок событий коррелирует со временем, в которое оно происходит.

Однако эта ментальная модель не работает в распределенной системе. В распределенной среде нет понятия времени, потому что нет единственного источника истины (глобальных часов). Причем события обычно происходят одновременно (в одно время) и в разных местах.

Поскольку мы не можем определить порядок на основе времени, нам трудно определить, происходит ли событие A до события B. Кроме того, события в распределенной системе не происходят одно за другим. Они могут происходить одновременно, параллельно или одновременно.

Общий или частичный заказ

Человеческий уровень времени - это взгляд как модель времени единой системы. Поскольку в единой системе используются одни унифицированные часы, центральная система часов может размещать событие в определенном порядке в зависимости от того, в какое время оно произошло. Когда мы знаем, когда в системе произойдет каждое событие, мы видим его общий порядок.

У каждого узла есть свои локальные часы в распределенной системе, но он не знает, сколько времени на других часах на другом узле. Этот узел может знать, как различать события внутри этого узла, но не может упорядочить текущее событие с событиями, происходящими на другом узле.

Следовательно, состояние распределенной системы - это частичный порядок, который не гарантирует ни сети, ни узлов в относительном порядке каждого узла. Однако каждый узел знает свой локальный порядок.

Например, мы знаем, что событие B происходит после события C, и идут A, B и C. Мы видим порядок B и C, но A может произойти в любое время. Следовательно, мы не знаем порядок A. Узел в системе не может быть уверен, когда приходят входящие сообщения или когда другой узел отправляет эти сообщения.

Если бы мы могли знать только частичный порядок. Как мы решаем вопросы заказа мероприятий?

Случайный порядок

Возможно, нам не нужно заботиться о времени для упорядочивания событий в нашей системе. Причина, по которой мы хотим знать о порядке, заключается в том, что мы хотим знать, что происходит. Следовательно, нам нужно заботиться не о точном времени, в которое происходит событие, а о том, как одно событие вызывает другое событие.

Случайный порядок событий - это упорядочивание событий не на основании того, когда они произошли, а на основе причинно-следственных связей. С помощью случайного заказа нам нужно знать не время события, а его причины и последствия. Таким образом, мы будем приблизительно знать порядок событий.

В упомянутой ранее проблеме мы можем определить, должно ли CreateEvent произойти до UpdateEvent на стороне потребителя. Однако с точки зрения обоих UpdateEvents мы не можем сказать, какое событие происходит раньше другого.

Мы можем попробовать разделить UpdateEvent, чтобы отправлять в очередь только UpdateEvent с увеличенным номером версии или порядковым номером атомарного счетчика. На приемных концах у нас может быть хранилище данных, в котором хранится номер версии, и мы будем проверять, не превышает ли входящее событие более чем на единицу текущая версия в хранилище данных. Если нет, мы можем использовать буфер, чтобы изменить порядок или снова поместить его в очередь, предполагая, что он не в порядке.

Предположим, вас больше интересует случайный заказ. В этом случае вы можете проверить логические часы или векторные часы, чтобы сгенерировать частичное упорядочение событий в распределенной системе и обнаружить нарушения причинно-следственной связи.

Если у вас есть какие-либо другие идеи или ссылки относительно решения проблем с заказом, поделитесь ими в разделе комментариев ниже.

Первоначально опубликовано на https://edward-huang.com.

Ресурсы