Привет, Хабр!

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

Основная цель такого разделения — минимизация радиуса поражения при возникновении сбоев и упрощение масштабирования системы.

Но вы наверное спросите: - А в чем же отличии от микросервисной архитектуры?

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

  1. Уровень изоляции:

    • Микросервисы разделяют приложение на независимые сервисы, каждый из которых выполняет определённую функцию или бизнес-логику. Эти сервисы могут общаться друг с другом через определённые API.

    • Клеточная архитектура уходит дальше, предлагая не только разделение по функциональности, но и по изоляции сред выполнения. Каждая клетка может содержать один или несколько микросервисов, но при этом они изолированы от других клеток в плане ресурсов, зависимостей и сетевых вызовов.

  2. Обработка сбоев:

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

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

  3. Масштабируемость:

    • Микросервисы предлагают масштабирование путём добавления экземпляров сервиса в зависимости от нагрузки.

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

Основные компоненты клеточной архитектуры

Маршрутизатор клеток: является центральным элементом, который управляет маршрутизацией запросов к соответствующим клеткам на основе ключа разделения. Этот ключ обычно связан с определенными атрибутами запроса, типа ID пользователя или ресурса. Маршрутизатор клеток должен быть максимально оптимизирован и иметь минимальную задержку, поскольку он обрабатывает все входящие запросы и направляет их в соответствующие клетки.

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

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

Где реализовали клеточную архитектуру

Slack

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

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

Система Slack построена так, что каждый сервис внутри AZ функционирует изолированно, обрабатывая только трафик внутри своей зоны. Это достигается за счёт применения различных сервисов обнаружения служб, таких как Envoy и Consul, которые поддерживают механизмы динамического управления трафиком и конфигураций.

Также Slack интегрирвла клеточную архитектуру с облачной инфраструктурой AWS, что позволило использовать возможности автоматического масштабирования и управления ресурсами на уровне облака, оптимизируя таким образом производительность и доступность сервисов. Это подчеркивает важность тесной интеграции клеточной архитектуры с облачными платформами для достижения наилучших результатов в управлении распределёнными системами.

Okta

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

Основная фича клеточной архитектуры Okta заключается в её способности к горизонтальному масштабированию с использованием таких инструментов, как Elasticsearch, Kinesis, ProxySQL, Redis и Storm, что позволяет линейно увеличивать количество клеток в зависимости от потребностей клиентов. Каждая клетка Okta предназначена для работы с определенным объемом трафика, и при ее насыщении система автоматически масштабируется, добавляя новые клетки.

Для управления выпуском обновлений и изменений Okta использует инструменты, моделирующие release trains, которые позволяют обновлять и масштабировать клетки без необходимости ручного вмешательства. Это обеспечивает единообразие развертывания артефактов во всех средах и позволяет параллельно выпускать апдейты с возможностью отката в случае сбоев.

Door dash

Основная цель DoorDash в переходе на клеточную архитектуру заключалась в уменьшении расходов на трансфер данных между различными зонами доступности при использовании микросервисов. Традиционная архитектура с балансировкой нагрузки типа round-robin приводила к значительным затратам из-за трафика, пересекающего границы AZ.

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

Пример конфигурации для Envoy:

resources:
 - "@type": type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment
   cluster_name: payment-service.service.prod.ddsd
   endpoints:
     - locality:
         zone: us-west-2a
       lb_endpoints:
         - endpoint:
             address:
               socket_address:
                 address: 1.1.1.1
                 port_value: 80
     - locality:
         zone: us-west-2b
       lb_endpoints:
         - endpoint:
             address:
               socket_address:
                 address: 2.2.2.2
                 port_value: 80
     - locality:
         zone: us-west-2c
       lb_endpoints:
         - endpoint:
             address:
               socket_address:
                 address: 3.3.3.3
                 port_value: 80

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

Решение этой проблемы часто решается использованием централизованных дашбордов и мониторинга, к примеру как это реализовано в Amazon CloudWatch, что позволяет следить за состоянием всех клеток в реальном времени и быстро реагировать на любые проблемы.

Помимо этого, каждая клетка должна иметь четко определенные политики безопасности и управления данными. Для этого можно реализовать автоматизацию и обновление клеток через AWS Step Functions и AWS CodeDeploy.


Больше практических навыков по архитектуре приложений вы можете получить в рамках практических онлайн-курсов от экспертов отрасли.

Комментарии (12)


  1. kozlov_de
    21.04.2024 13:54
    +2

    TL;DR

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

    То есть ничего нового

    И не марайте термин cell-based architecture

    Устоявшегося применения термина нет, но есть варианты и получше

    Например, умное шардирование БД с зеркалированием

    https://habr.com/ru/companies/vk/articles/807685/


  1. Apoheliy
    21.04.2024 13:54

    Вопрос про производительность и наподумать:

    Если содержимое одной клетки существует изолированно и при крэшах и т.п. восстановление идёт целой клетки, то возможно ли ускорить взаимодействие в микросервисах, используя менее изолированные механизмы?

    Как предел такой гранулярностив клетки: переход от микросервисов к монолитным "клеткам", в которых вместо сетевого взаимодействия и других (огромных) накладных расходов будут использоваться существенно быстрые механизмы: прямой вызов функций и т.п.

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

    В общем: при наличии клеток, нужны ли микросервисы?


  1. nronnie
    21.04.2024 13:54
    +4

    Я так и не понял из статьи - чем все-таки это отличается от обычных микросервисов? Микросервисы точно так же изолированы в отдельных процессах/контейнерах, самодостаточны, т.к. не используют никакие общие данные и общаются между собой только через свои API, что касается балансировки - так для этого везде используются API gateway. Что нового-то? Если для них придумали свое название, значит что-то есть, но, что именно - из статьи это вообще непонятно.


  1. Batalmv
    21.04.2024 13:54

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

    Вечный миф "модных" архитектур :) Ну как вы это можете решить, если он клетка ЛОГИЧЕСКИ зависит от другой?

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

    Что увеличивает накладные расходы

    В целом, разница наверное есть, но мне кажется это все многообразие "терминов" чисто кому-то поприкалываться на собеседованиях


    1. nronnie
      21.04.2024 13:54

      Вечный миф "модных" архитектур :) Ну как вы это можете решить, если он клетка ЛОГИЧЕСКИ зависит от другой?

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


      1. Batalmv
        21.04.2024 13:54

        Так и я про это

        В монолите запилить аналогичную логику без проблем, да и вообще - в любом варианте "компоновки кода"


        1. nronnie
          21.04.2024 13:54

          Большой шкаф монолит громче падает :) Монолит-то как раз если и упадет, то целиком. Хорошо еще если это будет какой-то "случайный" сбой, например со стороны железа - от этого можно еще заранее подстраховаться сделав кластер из монолитов (хотя опять-таки есть вещи, например БД, если реляционная, которые либо вообще не шардируются, либо шардируются с какими-то оговорками, ограничениями и костылями). А если сбой от того что задеплоили какой-то кривой код? Откатывать весь полностью кластер? Тут как-то совершенно правильно кто-то писал, что вопрос "монолит или микросервис" он лежит больше не в технической, а в административной плоскости, т.е. в плоскости организации процессов разработки, тестирования, развертывания и сопровождения.


          1. Batalmv
            21.04.2024 13:54

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

            Согласен, для меня главное и чуть ли не единственное преимущество микросервисов - это CI/CD и все, что с этим связано

            Про падение - ну, монолит также отлично растягивается горизонтально и в кластера


            1. nronnie
              21.04.2024 13:54

              монолит также отлично растягивается горизонтально и в кластера

              Да, я об этом упомянул. Но, монолит надо растягивать полностью, а в микро- можно выборочно что-то, что нужно растянуть, а что не нужно - наоборот укоротить. И опять-таки всё еще остаётся проблема "растягивания" БД, если это не NoSql.


              1. Batalmv
                21.04.2024 13:54

                Ну смотрите. Растягивание приложения - это по сутибольше декларативная задача, чем что либо еще.

                Есть ядра и память, реальные. Ядра потребляются не задоплоенными сервисами, а реальными вызовами. Т.е. есть к примеру монолит презентует два сервиса, один вызвали один раз, второй - 1000 раз, но реальное маштабирование произошло внутри монолита, в котором было инциировано создание 1001 потока. Каждый из них взял чуток памяти и проца для обоработки. Если вы не уперлись в пул запросов, и хватило ресурсов - все обработается. В случае микросервисов все тоже самое.Что интересно. если ситуация поменяется, и первый вызовую 1000 раз, а второй - один: то монолиту будет по фиг

                Если у вас "автоскейлинг" без изменения физических ресурсов, это просто "решение", котороя для монолита в большинстве случаев просто не актуально и все.

                Микросервисы ведь не дали вам больше ядер и памяти, они просто дали вам явно решить ту задачу, которая и так решена.

                --------------------------

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

                --------------------------

                База - все упирается в транзакционность и распределенность. Если у вас "вторая нода" далеко, то все равно вы делаете выбор между "гарантированными транзакциями" либо "скоростью в обмен на провисание RPO". NoSQL никакого чуда не дает, так как скорость передачи данных по сети для всех одинакова


                1. nronnie
                  21.04.2024 13:54

                  Насчет масштабирования это да, но микросервисам ведь можно и самих физических ресурсов выделять гранулировано - кому надо побольше, кому не надо - поменьше. Про БД, полноценное шардирование это еще и надежность. Выход из строя одного узла все равно оставляет доступной всю базу целиком. "Обычную" БД на каком RAIDе не размести - все равно, выйдет из строя узел с эти рейдом и вся база недоступна. Монолит, конечно, по любому проще во всех отношениях и надо сто раз подумать перед тем как от него в пользу микро- отказываться. На опыте уже пройденная тема, когда берут люди монолит, распихают его частями по паре дюжин контейнеров, внутрипроцессные вызовы заменят на service bus - "Йоу, смотрите все - у нас теперь все на микросервисах", а на деле все это тот же монолит, только еще и со всеми сложностями микро- связанными с распределенностью.


                  1. Batalmv
                    21.04.2024 13:54

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

                    Это не имеет значения, так как вас в конечном итоге надо "платить" за все физические ресурсы, которые тратятся

                    Просто та "проблема", которой нет в монолите, в микросервисах есть и ее надо решать

                    А гранулированно нарезать физические ресурсы как правило не выйдет, так как их добавлять долго + все равно нужен запас на "пик" либо отказ "ноды" (чтобы остальные подхватили ее нагрузку)

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

                    Некоторые, даже реляционные базы умеют в "кластер" (тогда выход одной ноды не критичен), а также в "резервные горячие" копии (тогда не критична потеря узла с данными). Собирая вместе "кластер" + "стендбай" у нас все хорошо :)

                    NoSQL делает все ровно тоже самое, записывая изменения на несколько нод. Никакой магии нет :)

                    -------------------

                    В целом любое решение вы растягиваете:

                    • ноды исполнения в кластер для обеспечения отказоустойчивости сервиса + балансер для раздачи нагрузки (который в свою очередь либо в кластере, либо часть клиента)

                    • места хранения данных на несколько "дисков" с записбю в несколько мест (с балансом между скорострельностью и "непотерей данных")

                    Плюс доавляется "обсервер" для предотвращения split brain и обеспечения "кворума" (там где он есть)

                    Понятно не все технологии в реальной жизни работают так, как обещают, но это чисто вопрос технологии и все

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

                    Лично я беру микросервисы, так как не хочу "писать против ветра" ну и все таки в части CI/CD микросервисы имеют объективные преимущества, которые на монолите недостижимы

                    И их недостатки - ну мне как архитектору куда интереснее. Монолит в целом скушно и успешно :) А тут поработать надо :)