Всем привет!
В прошлом посте я "забыл" про еще один, возможно ключевой аспект NoSQL хранилищ. А именно способность к горизонтальному масштабированию.
Почему ключевой - потому что причиной возникновения многих если не всех NoSQL решений стала недостаточная производительность RDBMS. А производительность начиная с некоторого момента (оптимальная архитектура, оптимальный запрос к СУБД, есть все индексы) прямо связана с возможностью масштабирования.
RDBMS как правило масштабируются горизонтально, а как я уже писал для этого способа есть физические ограничения - частота и число ядер процессора, сложность материнской платы.
Да, для реляционных СУБД часто есть репликация master-slave из коробки https://www.dmosk.ru/miniinstruktions.php?mini=postgresql-replication#master. Все примеры здесь и далее приведу для PostgreSQL.
Но в системе master-slave все равно есть узкое место в виде master-а, через которого идут все записи. Т.е. решение подходит для отчетных БД и для систем, где нагрузка на чтение в разы больше нагрузки на запись.
Да, есть сторонние библиотеки для репликации master-master https://github.com/bucardo/bucardo
Но появились они относительно недавно (думаю в ответ на популярность NoSQL). Часто это сторонние решения, и в любом случае гибкость SQL в плане выборки данных и строгая транзакционность плохо сочетаются с работой в режиме master-master.
Этих проблем нет в NoSQL, более того, они изначально проектируются для разрешения конфликтов чтения и записи с помощью таких средств, как вектора изменений, автоматический выбор master-а, обновление при чтении, возможность настройки степени согласованности данных. Это отдельная большая тема, в одном посте ее раскрыть невозможно.
Да, важное замечание - это не касается графовых хранилищ, т.к. для выборки может понадобиться обойти весь граф, а, следовательно, он должен храниться на одном сервере, в этом они похожи на традиционные реляционные СУБД.
#NoSQL #scalability
В прошлом посте я "забыл" про еще один, возможно ключевой аспект NoSQL хранилищ. А именно способность к горизонтальному масштабированию.
Почему ключевой - потому что причиной возникновения многих если не всех NoSQL решений стала недостаточная производительность RDBMS. А производительность начиная с некоторого момента (оптимальная архитектура, оптимальный запрос к СУБД, есть все индексы) прямо связана с возможностью масштабирования.
RDBMS как правило масштабируются горизонтально, а как я уже писал для этого способа есть физические ограничения - частота и число ядер процессора, сложность материнской платы.
Да, для реляционных СУБД часто есть репликация master-slave из коробки https://www.dmosk.ru/miniinstruktions.php?mini=postgresql-replication#master. Все примеры здесь и далее приведу для PostgreSQL.
Но в системе master-slave все равно есть узкое место в виде master-а, через которого идут все записи. Т.е. решение подходит для отчетных БД и для систем, где нагрузка на чтение в разы больше нагрузки на запись.
Да, есть сторонние библиотеки для репликации master-master https://github.com/bucardo/bucardo
Но появились они относительно недавно (думаю в ответ на популярность NoSQL). Часто это сторонние решения, и в любом случае гибкость SQL в плане выборки данных и строгая транзакционность плохо сочетаются с работой в режиме master-master.
Этих проблем нет в NoSQL, более того, они изначально проектируются для разрешения конфликтов чтения и записи с помощью таких средств, как вектора изменений, автоматический выбор master-а, обновление при чтении, возможность настройки степени согласованности данных. Это отдельная большая тема, в одном посте ее раскрыть невозможно.
Да, важное замечание - это не касается графовых хранилищ, т.к. для выборки может понадобиться обойти весь граф, а, следовательно, он должен храниться на одном сервере, в этом они похожи на традиционные реляционные СУБД.
#NoSQL #scalability
www.dmosk.ru
Настройка репликации PostgreSQL. Отказоустойчивый кластер баз данных Postgre
Пошаговая инструкция по настройке асинхронной потоковой репликации на СУБД PostgreSQL. Подготовка сервера, редактирование конфигурационных файлов, настройка Master, Slave.
Всем привет!
Как можно масштабировать нагрузку в облаке? Под облаком я понимаю 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
Как можно масштабировать нагрузку в облаке? Под облаком я понимаю 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
Kubernetes
Horizontal Pod Autoscaling
In Kubernetes, a HorizontalPodAutoscaler automatically updates a workload resource (such as a Deployment or StatefulSet), with the aim of automatically scaling the workload to match demand.
Horizontal scaling means that the response to increased load is to…
Horizontal scaling means that the response to increased load is to…