26 февраля мы провели встречу Apache Ignite GreenSource, на которой выступили участники проекта с открытым исходным кодом.
Важным событием в жизни этого сообщества стала реструктуризация компонента Зажгите сервисную сеть , что позволяет развертывать пользовательские микросервисы непосредственно в кластере Ignite. Об этом непростом процессе он рассказал на митапе Вячеслав Дарадур , старший разработчик Яндекса и участник Apache Ignite более двух лет.
Начнем с того, что вообще представляет собой Apache Ignite. Это база данных, представляющая собой распределенное хранилище ключей/значений с поддержкой SQL, транзакций и кэширования.
Кроме того, Ignite позволяет развертывать собственные сервисы непосредственно в кластере Ignite. Разработчик имеет доступ ко всем инструментам, которые предоставляет Ignite — распределенным структурам данных, обмену сообщениями, потоковой передаче, вычислениям и сетке данных.
Например, при использовании Data Grid исчезает проблема администрирования отдельной инфраструктуры для хранения данных и, как следствие, возникающие накладные расходы.
С помощью Service Grid API вы можете развернуть сервис, просто указав в конфигурации схему развертывания и, соответственно, сам сервис.
Обычно схема развертывания указывает количество экземпляров, которые следует развернуть на узлах кластера.
Существует две типичные схемы развертывания.
Первый — Cluster Singleton: в любой момент времени в кластере гарантированно доступен один экземпляр пользовательской службы.
Второй — Node Singleton: на каждом узле кластера развертывается один экземпляр сервиса.
Пользователь также может указать количество экземпляров сервиса во всем кластере и определить предикат для фильтрации подходящих узлов.
В этом сценарии Service Grid сама рассчитает оптимальное распределение для развертывания сервисов.
Кроме того, есть такая функция, как Affinity Service. Affinity — это функция, определяющая отношение ключей к разделам и отношение сторон к узлам топологии.
С помощью ключа можно определить основной узел, на котором хранятся данные.
Таким образом, вы можете связать свой собственный сервис с кешем ключей и функций сходства.
Если функция сходства изменится, произойдет автоматическое перераспределение.
Таким образом, сервис всегда будет расположен рядом с данными, которыми он должен манипулировать, и, соответственно, уменьшит накладные расходы на доступ к информации.
Эту схему можно назвать разновидностью коллокированных вычислений.
Теперь, когда мы разобрались, в чем прелесть Service Grid, давайте поговорим об истории его развития.
Что произошло раньше
Предыдущая реализация Service Grid была основана на реплицируемом транзакциях системном кэше Ignite. Слово «кэш» в Ignite относится к хранилищу.То есть это не что-то временное, как можно подумать.
Несмотря на то, что кэш реплицируется и каждый узел содержит весь набор данных, внутри кэша он имеет секционированное представление.
Это связано с оптимизацией хранилища.
Что произошло, когда пользователь захотел развернуть службу?
- Все узлы кластера подписались на обновление данных в хранилище с помощью встроенного механизма Continuous Query.
- Инициирующий узел в рамках транзакции с подтверждением чтения сделал запись в базе данных, содержащую конфигурацию службы, включая сериализованный экземпляр.
- При получении уведомления о новой записи координатор рассчитывал распределение на основе конфигурации.
Полученный объект был записан обратно в базу данных.
- Узлы считывают информацию о новом дистрибутиве и развернутых сервисах в
если необходимо.
Что нам не подошло
В какой-то момент мы пришли к выводу: так нельзя работать с сервисами.Причин было несколько.
Если при развертывании произошла какая-то ошибка, то узнать ее можно было только из логов узла, где все произошло.
Было только асинхронное развертывание, поэтому после возврата управления пользователю из метода развертывания требовалось какое-то дополнительное время для запуска сервиса — и за это время пользователь не мог ничем управлять.
Чтобы дальше развивать Service Grid, создавать новые функции, привлекать новых пользователей и делать жизнь каждого проще, нужно что-то менять.
При проектировании нового Service Grid мы в первую очередь хотели обеспечить гарантию синхронного развертывания: как только пользователь вернул управление из API, он сразу же мог воспользоваться сервисами.
Я также хотел дать инициатору возможность обрабатывать ошибки развертывания.
Кроме того, хотелось упростить реализацию, а именно уйти от транзакций и ребалансировки.
Несмотря на то, что кэш реплицируется и балансировки нет, при большом развертывании с множеством нод возникли проблемы.
При изменении топологии узлам необходимо обмениваться информацией, а при большом развертывании эти данные могут весить немало.
Когда топология была нестабильной, координатору приходилось пересчитывать распределение услуг.
Да и вообще, когда приходится работать с транзакциями в нестабильной топологии, это может привести к труднопрогнозируемым ошибкам.
Проблемы
Какие глобальные изменения без сопутствующих проблем? Первым из них было изменение топологии.Нужно понимать, что в любой момент, даже в момент развертывания сервиса, узел может войти в кластер или выйти из него.
Более того, если на момент развертывания узел присоединится к кластеру, необходимо будет последовательно передать всю информацию об услугах на новый узел.
И речь идет не только о том, что уже развернуто, но и о текущих и будущих развертываниях.
Это лишь одна из проблем, которую можно собрать в отдельный список:
- Как развернуть статически настроенные сервисы при запуске узла?
- Выход узла из кластера — что делать, если на узле размещены сервисы?
- Что делать, если поменялся координатор?
- Что делать, если клиент повторно подключается к кластеру?
- Необходимо ли обрабатывать запросы на активацию/деактивацию и каким образом?
- Что, если бы они потребовали уничтожения кэша, и к этому были бы привязаны аффинити-сервисы?
Решение
В качестве цели мы выбрали подход, управляемый событиями, с реализацией взаимодействия процессов с помощью сообщений.
В Ignite уже реализованы два компонента, которые позволяют узлам пересылать сообщения между собой — communication-spi и Discovery-SPI.
Communication-spi позволяет узлам напрямую общаться и пересылать сообщения.
Он хорошо подходит для отправки больших объемов данных.
Discovery-spi позволяет отправлять сообщение всем узлам кластера.
В стандартной реализации это делается с использованием кольцевой топологии.
Также есть интеграция с Zookeeper, в этом случае используется топология звезда.
Еще один важный момент, на который стоит обратить внимание, — Discovery-spi предоставляет гарантии того, что сообщение обязательно будет доставлено в правильном порядке всем узлам.
Давайте посмотрим на протокол развертывания.
Все запросы пользователей на развертывание и отмену развертывания отправляются через Discovery-SPI. Это дает следующее гарантии :
- Запрос будет получен всеми узлами кластера.
Это позволит запросу продолжить обработку при смене координатора.
Это также означает, что в одном сообщении каждый узел будет иметь все необходимые метаданные, такие как конфигурация сервиса и его сериализованный экземпляр.
- Строгий порядок доставки сообщений помогает разрешать конфликты конфигурации и конкурирующие запросы.
- Поскольку вхождение узла в топологию также обрабатывается через Discovery-SPI, новый узел получит все данные, необходимые для работы с сервисами.
Эти задачи ставятся в очередь, а затем обрабатываются в другом потоке отдельным исполнителем.
Это реализовано таким образом, поскольку развертывание может занять значительное время и недопустимо задержать дорогостоящий процесс обнаружения.
Все запросы из очереди обрабатываются менеджером развертывания.
У него есть специальный работник, который извлекает задачу из этой очереди и инициализирует ее для начала развертывания.
После этого происходят следующие действия:
- Каждый узел самостоятельно рассчитывает распределение благодаря новой детерминированной функции присваивания.
- Ноды генерируют сообщение с результатами развертывания и отправляют его координатору.
- Координатор агрегирует все сообщения и генерирует результат всего процесса развертывания, который отправляется через Discovery-SPI на все узлы кластера.
- При получении результата процесс развертывания завершается, после чего задача удаляется из очереди.
Новый дизайн, управляемый событиями: org.apache.ignite.internal.processors.service.IgniteServiceProcessor.java. Если во время развертывания возникает ошибка, узел немедленно включает эту ошибку в сообщение, которое отправляет координатору.
После агрегации сообщений координатор будет иметь информацию обо всех ошибках при развертывании и отправит это сообщение через Discovery-SPI. Информация об ошибках будет доступна на любом узле кластера.
Все важные события в Service Grid обрабатываются по этому алгоритму работы.
Например, изменение топологии — это тоже сообщение через Discovery-SPI. И вообще, по сравнению с тем, что было раньше, протокол оказался достаточно лёгким и надёжным.
Достаточно, чтобы справиться с любой ситуацией во время развертывания.
Что будет дальше
Теперь о планах.Любое серьезное изменение в проекте Ignite осуществляется как инициатива по улучшению Ignite, называемая IEP. Редизайн Service Grid также включает в себя IEP — ИЭП №17 с издевательским названием «Замена масла в Сервисной сети».
Но на самом деле мы меняли не моторное масло, а весь двигатель.
Мы разделили задачи ИЭП на 2 этапа.
Первый — это основной этап, который заключается в переработке протокола развертывания.
Он уже включен в мастер, вы можете попробовать новый Service Grid, который появится в версии 2.8. Второй этап включает в себя множество других задач:
- Горячее перераспределение
- Управление версиями службы
- Повышенная отказоустойчивость
- Тонкий клиент
- Инструменты для мониторинга и расчета различных метрик
Также приглашаем Вас посетить нас по адресу список разработчиков И список пользователей поделитесь своим опытом.
Ваш опыт действительно важен для сообщества; это поможет понять, куда двигаться дальше, как развивать компонент в дальнейшем.
Теги: #открытый исходный код #Хранение данных #Микросервисы #Apache #ignite
-
Играйте В Создателя Всего Сущего
19 Oct, 24 -
Восстановление Ос После Вируса-Вымогателя
19 Oct, 24 -
Iriver Выходит На Рынок Мобильных Телефонов
19 Oct, 24 -
Ошибка Форматирования Блоков Swift В Xcode
19 Oct, 24