(java || kotlin) && devOps
369 subscribers
6 photos
1 video
6 files
306 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

Есть такой интересный вопрос - можно ли поместить СУБД в облако?
Если отвечать на него строго технически - да, можно, для этого в k8s есть специальные типы объектов - StatefulSet https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ и PersistentVolume
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
которые обеспечивают ряд требуемых для СУБД характеристик:
1) подключенное хранилище не удаляется при каждой остановке пода
2) экземпляр StatefulSet имеет постоянное имя
3) процедура масштабирования StatefulSet в обе стороны последовательна - поды добавляются\удаляются по одному

Более того, в документации кубера есть пример с раскатыванием MySQL https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application
Причем с возможностью автоматического масштабирования на чтение. Пример на самом деле меня впечатлил: сотня строк манифестов yaml - и БД уезжает в облако.

Так ли все хорошо?
Конечно же нет)
Для начала я бы задал типичный "менеджерский" вопрос - какую задачу решаем?

Первый момент - горизонтальное масштабирование на чтение можно обеспечить для любой СУБД. Как в облаке, так и без облака. На запись - только для NoSQL хранилищ с поддержкой шардирования.

Второй момент: сопровождение СУБД - это не просто гарантия наличия работоспособного инстанса на ПРОМ. Это еще и периодические бэкапы, откаты на резервную копию, начальное заполнение БД данными, заполнение "горячего" кэша, выбор нового master если старому плохо (leader election), тонкие настройки репликации и многое другое, чего я просто не знаю. А знают - хорошие DBA. Т.е. получается даже если мы поместим обычную СУБД в облако - DBA все равно нужен. Причем DBA, умеющий в облако, а это, кажется, редкая птица)

Т.е. все плохо? И снова нет. Если есть потребность отдать БД "на аутсорс" в облако, то выход - использование хранилищ от облачных провайдеров, спроектированных для работы в облаке. Там все вышеописанные тонкости будут учтены. Примеры:
1) Amazon Aurora https://habr.com/ru/companies/oleg-bunin/articles/471686/
2) YDB https://cloud.yandex.ru/ru/services/ydb
3) Azure Cosmos DB for PostgreSQL https://learn.microsoft.com/en-us/azure/cosmos-db/postgresql/introduction

Ну или хотя бы использование заточенных под работу в облаке СУБД. Вот пара примеров, первыми попавшихся мне на глаза:
1) Tarantool https://habr.com/ru/companies/vk/articles/533308/
2) CockroachDB https://www.cockroachlabs.com/docs/v23.2/deploy-cockroachdb-with-kubernetes
Как можно заметить, в обоих случаях есть специальный оператор k8s для управления кластером.

P.S. Тема сложная, интересная, поэтому думаю это не последняя статья.

#k8s #storage #cloud #rdbms
Всем привет!

Как можно масштабировать нагрузку в облаке? Под облаком я понимаю k8s как некий стандарт.

1) "ручками". Простой, но не надежный способ. Отягощающий фактор - не всегда у сопровождения ПРОМ есть права на смену настроек Deployment, тогда требуется отдельный деплой

2) выставить число подов и limits, соответствующими максимальной нагрузке. Еще проще, но совсем не рационально в плане использования ресурсов

3) HorizontalPodAutoscaler https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ Позволяет менять число подов сервиса при превышении некого порога нагрузки по cpu и memory. Порог - это не процент использования, а соотношения заданного requests с текущим значением. Подходит если требуемая нагрузка может превышать возможности 1 пода, и если сервис поддерживает горизонтальное масштабирование - т.е. stateless.

4) VerticalPodAutoscaler https://habr.com/ru/companies/flant/articles/541642/ Как следует из название - масштабирует поды вертикально. Тут есть нюанс - на данный момент k8s не позволяет менять requests и limits у пода "на ходу". Данная фича называется In-Place Update of Pod Resources и пока находится в бета-версии https://github.com/kubernetes/enhancements/issues/1287
Сейчас VerticalPodAutoscaler может следующее:
а) на основе истории использования подом ресурсов рассчитать и выдать рекомендуемые значения
б) применить эти значения при очередном плановом рестарте
в) самому рестартовать под
Подходит для следующих случаев:
а) statefull сервисы типа хранилища данных в облаке StatefullSet, для которых горизонтальное масштабирование или невозможно, или не приветствуется
б) "легкие" сервисы, которым достаточно одной реплики (или двух по требованиям надежности)
Из особенностей - не гарантируется корректная работа совместно с HorizontalPodAutoscaler по одним и тем же метрикам cpu и memory. И не работает с Java приложениями в плане нагрузки по памяти, т.к. Java сама управляет памятью, а VerticalPodAutoscaler эти данные не видит.
Ну и главный минус - необходимость рестарта для применения настроек

5) как избавиться от необходимости рестарта? Дождаться полноценного внедрения In-Place Update of Pod Resources и доработки VerticalPodAutoscaler. Или использовать бета-версию In-Place Update of Pod Resources реализовать соответствующий k8s controller самому. Это уже сделано: https://piotrminkowski.com/2023/08/22/resize-cpu-limit-to-speed-up-java-startup-on-kubernetes/
Данная реализация не умеет сама рассчитывать рекомендуемые значения requests. Зато позволяет красиво проблему JVM приложений, о которой я уже писал ранее - проблему долгого старта. Java, а точнее Spring приложение, при старте производит достаточно ресурсоемкую настройку контекста. Речь идет про обычный Spring Boot без применения всех возможных способов ускорить запуск. Если память после первоначальной настройки так и остается занятой созданными бинами, то cpu при старте требуется сильно больше, чем при обычной работе. Что с этим делать?
а) Не выделять лишние cpu - время старта увеличивается в разы
б) Пойти по пути, описанному в п.2 - выдать максимум ресурсов. Тогда может получиться, что мы тратим cpu на быстрый старт приложения, а далее ресурсы не утилизируются
в) In-Place Update of Pod Resources
Конкретно по данной реализации - мне она кажется не идеальной, т.к. ресурс по cpu настраивается в 2 манифестах, это не наглядно и способствует внесению несогласованных правок. Но решение в целом - полезное.

#k8s #cloud #scalability
Всем привет!

Случайно наткнулся на старую статью - 2015 год - про переход с legacy на Service Oriented Architecture ака SOA.
И хочу сказать, что это хороший пример развития истории по спирали)

Что в статье актуально?
Заменяем слово SOA на микросервисы, и в целом все, что касается преимуществ микросервисной архитектуры и стратегии перехода на нее - актуально. Микросервисы = SOA 2.0 )))

REST оставляем, SOAP+XML заменяем на gRPC\GraphQL для тех случаев, когда требуется большая производительность и гибкость соответственно по сравнению с REST. К слову, недостаток производительности и гибкости - это основные проблемы SOAP. Ремарка - знаю места, где SOAP еще жив (интеграция с госорганами), но он в любом случае вымирает.

ESB, трудности реализации асинхронного взаимодействия - все эти задачи взяла на себя Kafka. Прорывной инструмент - быстрый, надежный (обеспечивает дешевую персистентность), opensource, простой с точки зрения разработчика. В т.ч. потому, что нет необходимости разрабатывать логику маппинга сообщений на брокере. Да, он реализует только одну из двух основных моделей асинхронного взаимодействия - Publisher-Subscriber - и не реализует Message Queue. Но понятно, что топиками можно пользоваться как заменой очередей, и в большинстве случаев проблем при этом не будет.

Облачные решения - за 10 лет из вызова превратились в новую реальность)

А вызов сейчас - внедрение AI. Как-то так)

#microservices #ai #cloud #kafka #rest