Pull to refresh

Comments 17

Здравствуйте, Александр!

Встроенный в k8s механизм Liveness- и Readiness-проб позволяет не беспокоиться, что приложение начало тормозить или вовсе перестало отвечать


В смысле? Каким образом k8s отменяет борьбу с «тормозами»? Просто перезапуск приложения или что-то иное?
Тормоза в приложениях зачастую бывают если на каком то участке образуется узкое горлышко, например образуется очередь ожидания в пуле соединений к БД или очередь потоков в пуле вебсервера. В этом случае может помочь Readiness проба, временно отключив трафик на проблемный узел. Тормоза могут возникнуть также если на узле отвалился внешний кэш или же проблема с самой виртуалкой, на которой создан под, переполнился heap, и тд, мы можем дать узлу приложения какое то время чтобы придти в себя, а если это не помогло просто поднять новый под сервиса и перевести часть трафика на него. Конечно если проблема в самом приложении нас это не спасет. Но если вдруг достигнут предел пропускной способности можно так же использовать механизм Autoscaling (HorizontalPodAutoscaler) в k8s
С Readiness пробой надо быть аккуратнее, т.к. она может не только временно отключать новый траффик на поду, но также и убивать поду которая долго не ready не смотря на то, что данная пода находится под нагрузкой (обрабатывая долгоживующие операции, например).
И потом возникает эффект лавины
Типичный антипаттерн

Поды убиваются не от readiness, а от liveness probes.

Резонное замечание. Мы с таким еще не сталкивались. Предполагаю, что в таком случае либо readiness-проба настроена недолжным образом, либо неправильно настроен health-check приложения. Хотя, кажется, что под может убить только liveness-проба

Кажется маловероятным что IMDG типа Ignite и Hazelcast не поддерживают broadcast репликацию.

Если есть решение без использования репликации, почему бы не использовать его?)

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

Я имер ввиду репликацию IMDG кластеров.
Репликация в Hazelcast довольно сложно устроена, конечно она учитывает множество тех самых "тонких мест". Но судя по отзыву коллег, использование Hazelcast влечёт за собой существенное увеличение потребления CPU и памяти. После выпиливания Hazelcast тесты показали существенное уменьшение этих показателей. Всё таки обычная реализация кэша выигрывает, как минимум отсутствует необходимость постоянной сериализации/десериализации. Также ввиду сложности устройства IMDG решений, люди сталкивались с проблемой конфигурации, когда количество узлов приложения >2. Сталкивались с проблемой дублирования и потерей информации при выкатывании новых версий приложения.

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

Downtime для нашего приложения недопустим.


Можно про это поподробнее? Каковы будут последствия, если та часть, которая отдает динамические данные, будет недоступна в течении, скажем, пары секунд в сутки?

При нагрузке в 500 rps за 2 секунды мы потеряем 1000 запросов от клиентов. Клиенты, которые не получат свои данные, открыв мобильное приложение, будут жаловаться на нестабильную работу. Недоступность сервиса приведёт к недовольным клиентам

При нагрузке в 500 rps за 2 секунды мы потеряем 1000 запросов от клиентов.


Почему потеряем? Мобильный клиент может получить код 503 и повторить запрос через секунду.

PS: Интерес не праздный, сейчас проектируем и разрабатываем highload систему, так что весьма интересно, как это делается.

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

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


Мы, к примеру, встречались с ситуацией, когда DNS-сервер в нашем Kubernetes кластере начал вести себя не очень хорошо. И все поды внутри кластера просто перестали резолвить друг друга. Вот Вам и бесшовность, и бесперебойная работа.


Интересность ситуации в том, что все установленные соединения (и уже зарезолвенные IP) продолжали работать. И проблема выплыла не сразу и сначала выглядела локальной: вот я пытаюсь поднять под (обновить один сервис, к примеру), но не получается.


К счастью, дело происходило на демо-серверах.




Не поддавайтесь иллюзии, что "облака" избавляют Вас от сложностей. Они только добавляют реальность сложности в инфраструктуру, а имеющуюся сложность — прячут.

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

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

А для повышения надежности можно использовать два физически разделенных k8s кластера с установленной рабочей версией приложения, а внешний балансировщик будет форвардить трафик на один исправный кластер, мы сейчас думаем переходить на такое решение.
Sign up to leave a comment.