Всем привет!
Есть куча способов работать с реляционными СУБД в Java приложениях.
JPA, JPA JPQL, JPA Native Query, JPA Criteria API, Spring Data JDBC, Spring Data JPA, MyBatis, Jooq. Нативный JDBC в конце концов. Чистый Hibernate API не беру в расчет, т.к. подозреваю, что JPA его заборол)
А недавно я узнал про еще один - в нем соединяются JPA и стримы.
Речь о JPAStreamer https://jpastreamer.org/
Плюс статья на хабре https://habr.com/ru/post/568794/
Идея кажется интересной, т.к. благодаря автогенерации недостающих классов получаем строгую проверку типов на этапе компиляции. И запрос в теле метода, а не в аннотации.
При этом код выглядит более читаемый по сравнению с Criteria API, который так и не взлетел.
Если попытаться сравнить еще с чем-то - код похож на Jooq, но на основе JPA и со стримами. И на .NET LINQ.
Возникла мысль: неплохо бы сделать сравнение вышеперечисленных технологий. Имеет смысл?
#jpa #jdbc #rdbms
Есть куча способов работать с реляционными СУБД в Java приложениях.
JPA, JPA JPQL, JPA Native Query, JPA Criteria API, Spring Data JDBC, Spring Data JPA, MyBatis, Jooq. Нативный JDBC в конце концов. Чистый Hibernate API не беру в расчет, т.к. подозреваю, что JPA его заборол)
А недавно я узнал про еще один - в нем соединяются JPA и стримы.
Речь о JPAStreamer https://jpastreamer.org/
Плюс статья на хабре https://habr.com/ru/post/568794/
Идея кажется интересной, т.к. благодаря автогенерации недостающих классов получаем строгую проверку типов на этапе компиляции. И запрос в теле метода, а не в аннотации.
При этом код выглядит более читаемый по сравнению с Criteria API, который так и не взлетел.
Если попытаться сравнить еще с чем-то - код похож на Jooq, но на основе JPA и со стримами. И на .NET LINQ.
Возникла мысль: неплохо бы сделать сравнение вышеперечисленных технологий. Имеет смысл?
#jpa #jdbc #rdbms
JPAstreamer
JPAstreamer | Express Hibernate Queries as Java Streams
JPAstreamer is an open source toolkit that enriches the API of any JPA provider to allow processing data as standard Java Streams.
👍6
Всем привет!
Есть такой интересный вопрос - можно ли поместить СУБД в облако?
Если отвечать на него строго технически - да, можно, для этого в 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 - и БД уезжает в облако.
Так ли все хорошо?
Конечно же нет)
Для начала я бы задал типичный "менеджерский" вопрос - какую задачу решаем?
Первый момент - горизонтальное масштабирование на чтение можно обеспечить для любой СУБД. Как в облаке, так и без облака. На запись - тоже можно, например, прикладным шардированием.
Второй момент: сопровождение СУБД - это не просто гарантия наличия работоспособного инстанса на ПРОМ. Это еще и периодические бэкапы, откаты на резервную копию, начальное заполнение БД данными, заполнение "горячего" кэша, выбор нового 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 есть специальные типы объектов - 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 - и БД уезжает в облако.
Так ли все хорошо?
Конечно же нет)
Для начала я бы задал типичный "менеджерский" вопрос - какую задачу решаем?
Первый момент - горизонтальное масштабирование на чтение можно обеспечить для любой СУБД. Как в облаке, так и без облака. На запись - тоже можно, например, прикладным шардированием.
Второй момент: сопровождение СУБД - это не просто гарантия наличия работоспособного инстанса на ПРОМ. Это еще и периодические бэкапы, откаты на резервную копию, начальное заполнение БД данными, заполнение "горячего" кэша, выбор нового 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
Kubernetes
StatefulSets
A StatefulSet runs a group of Pods, and maintains a sticky identity for each of those Pods. This is useful for managing applications that need persistent storage or a stable, unique network identity.
🔥5
Всем привет!
Наверное все здесь знают, что такое UUID. Universally Unique IDentifier. Можно использовать как искусственный ключ. С высокой точностью обеспечивает уникальность, хотя и не 100%. Казалось бы, о чем здесь можно рассказывать. Ну и UUID и UUID.
А если я скажу, что недавно вышла 7-я (!) версия стандарта?) Для меня это было сюрпризом.
Вот описание первых 5 версий: https://habr.com/ru/companies/vk/articles/522094/
Вот - какие проблемы решает 7-й https://www.pvsm.ru/sistemnoe-programmirovanie/367012
А вот генератор разных версий с кратким описанием каждой: https://idtools.co/uuid/v7
Если вкратце про суть проблемы - UUID часто используют в БД как ключ. Но при таком использовании у него есть один большой минус - значения UUID не возрастают монолитно, как, например, обычный инкремент. Где это может быть полезно - сортировка и партиционирование таблиц.
Что интересно - в первой версии UUID было зашито время, а время - это тоже счетчик, в формате "с начала эпохи" или Unix time. Но в первой версии время хранилось в 2 разных частях UUID, причем еще и в перевернутом виде.
А 6-я версия - легкая модификация 1-й, где первый блок, содержащий время, хранят в нормальном формате и по таким UUID возможна сортировка.
#uuid #rdbms
Наверное все здесь знают, что такое UUID. Universally Unique IDentifier. Можно использовать как искусственный ключ. С высокой точностью обеспечивает уникальность, хотя и не 100%. Казалось бы, о чем здесь можно рассказывать. Ну и UUID и UUID.
А если я скажу, что недавно вышла 7-я (!) версия стандарта?) Для меня это было сюрпризом.
Вот описание первых 5 версий: https://habr.com/ru/companies/vk/articles/522094/
Вот - какие проблемы решает 7-й https://www.pvsm.ru/sistemnoe-programmirovanie/367012
А вот генератор разных версий с кратким описанием каждой: https://idtools.co/uuid/v7
Если вкратце про суть проблемы - UUID часто используют в БД как ключ. Но при таком использовании у него есть один большой минус - значения UUID не возрастают монолитно, как, например, обычный инкремент. Где это может быть полезно - сортировка и партиционирование таблиц.
Что интересно - в первой версии UUID было зашито время, а время - это тоже счетчик, в формате "с начала эпохи" или Unix time. Но в первой версии время хранилось в 2 разных частях UUID, причем еще и в перевернутом виде.
А 6-я версия - легкая модификация 1-й, где первый блок, содержащий время, хранят в нормальном формате и по таким UUID возможна сортировка.
#uuid #rdbms
Хабр
Как генерируются UUID
Вы наверняка уже использовали в своих проектах UUID и полагали, что они уникальны. Давайте рассмотрим основные аспекты реализации и разберёмся, почему UUID практически уникальны, поскольку существует...
🔥4❤2
Всем привет!
Я сейчас на Highload-е. Оффлайн.
Сделаю серию заметок по докладам, которые посетил. Названия докладов примерные)
Нужен ли кэш при работе с современными БД?
Казалось бы ответ очевиден, но нет) В смысле не всегда.
Если брать инстанс СУБД Postgres или MySQL - да, кэш будет быстрее, но не то, что на порядок - даже не в разы. Два основных условия - инстанс БД используется только для чтения и используется актуальная версия СУБД. Более того - они ещё и неплохо масштабируются по ядрам CPU. Вопрос что дешевле - держать сервер кэша или ещё один сервер СУБД. В общем эффективность кэша нужно подтверждать на НТ.
Еще одно открытие для меня - MySQL не сильно медленнее Postgres. А пропатченный - даже быстрее. У меня был травматический опыт десятилетней давности с MySQL и обратное представление)
P.S. Если кто ещё на конференции?
#rdbms #caching
Я сейчас на Highload-е. Оффлайн.
Сделаю серию заметок по докладам, которые посетил. Названия докладов примерные)
Нужен ли кэш при работе с современными БД?
Казалось бы ответ очевиден, но нет) В смысле не всегда.
Если брать инстанс СУБД Postgres или MySQL - да, кэш будет быстрее, но не то, что на порядок - даже не в разы. Два основных условия - инстанс БД используется только для чтения и используется актуальная версия СУБД. Более того - они ещё и неплохо масштабируются по ядрам CPU. Вопрос что дешевле - держать сервер кэша или ещё один сервер СУБД. В общем эффективность кэша нужно подтверждать на НТ.
Еще одно открытие для меня - MySQL не сильно медленнее Postgres. А пропатченный - даже быстрее. У меня был травматический опыт десятилетней давности с MySQL и обратное представление)
P.S. Если кто ещё на конференции?
#rdbms #caching
🔥1
Ещё один интересный момент про кэши: кэши - этот не только про скорость. Ещё два плюса:
1) более простой API, по крайней мере по сравнению с традиционным реляционными БД. noSQL решения играют на том же поле. Условно getByKey() сильно проще, чем SELECT a,b,c FROM x INNER JOIN ... Сложность выборки данных прячется в сервисе, заполняющем кэш
2) кэши в общем случае лучше масштабируются, вертикально и горизонтально, за счёт более простого устройства. Ключевое слово - в общем случае, как раз на докладе показали, что не все так хорошо
И сразу один жирный минус: усложнение системы, дублирование данных, синхронизация, допустимость устаревших данных...
#rdbms #caching
1) более простой API, по крайней мере по сравнению с традиционным реляционными БД. noSQL решения играют на том же поле. Условно getByKey() сильно проще, чем SELECT a,b,c FROM x INNER JOIN ... Сложность выборки данных прячется в сервисе, заполняющем кэш
2) кэши в общем случае лучше масштабируются, вертикально и горизонтально, за счёт более простого устройства. Ключевое слово - в общем случае, как раз на докладе показали, что не все так хорошо
И сразу один жирный минус: усложнение системы, дублирование данных, синхронизация, допустимость устаревших данных...
#rdbms #caching
Всем привет!
Окей, транзакции в Kafka и в БД по отдельности у нас есть. А можно объединить их в одной транзакции?
Во-первых у нас есть паттерн Сага.
А во-вторых - YDB (от Яндекса).
Вообще интересно развивалась данная СУБД. Вначале это было быстрое и горизонтально масштабируемое облачное noSQL хранилище с полноценными транзакциями. Потом разработчикам не понравилось, как работает Kafka в многопользовательском режиме, и они добавили в YDB топики. Ещё один плюс - не надо отдельно разворачивать Kafka. И наконец «финалочка» - появилась поддержка транзакций топики+таблицы. Паттерн Transaction outbox - давай, до свидания)
Вообще людям, которые могут себе позволить облако Яндекса по финансовым и идеологическим соображениям, не завязанных на существующий технологический стек - им можно только позавидовать)
Ложка дёгтя - транзакции в YDB пока работают медленнее Kafka. И медленнее, чем хотелось бы команде Яндекса. Команда работает над этим)
#rdbms #transactions #kafka #streaming
Окей, транзакции в Kafka и в БД по отдельности у нас есть. А можно объединить их в одной транзакции?
Во-первых у нас есть паттерн Сага.
А во-вторых - YDB (от Яндекса).
Вообще интересно развивалась данная СУБД. Вначале это было быстрое и горизонтально масштабируемое облачное noSQL хранилище с полноценными транзакциями. Потом разработчикам не понравилось, как работает Kafka в многопользовательском режиме, и они добавили в YDB топики. Ещё один плюс - не надо отдельно разворачивать Kafka. И наконец «финалочка» - появилась поддержка транзакций топики+таблицы. Паттерн Transaction outbox - давай, до свидания)
Вообще людям, которые могут себе позволить облако Яндекса по финансовым и идеологическим соображениям, не завязанных на существующий технологический стек - им можно только позавидовать)
Ложка дёгтя - транзакции в YDB пока работают медленнее Kafka. И медленнее, чем хотелось бы команде Яндекса. Команда работает над этим)
#rdbms #transactions #kafka #streaming
Как мне напомнили в комментариях - история развивается по спирали.
Очереди (очереди не равно топики Kafka) есть в Oracle https://docs.oracle.com/en/database/oracle/oracle-database/19/adque/aq-introduction.html
И они поддерживают общие транзакции с таблицами.
Также у Oracle есть шлюз для связывания внутренних и внешних очередей https://docs.oracle.com/en/database/oracle/oracle-database/21/adque/messaging_gateway.html
Аналогично для MSSQL https://learn.microsoft.com/ru-ru/sql/database-engine/service-broker/benefits-of-programming-with-service-broker?view=sql-server-ver16
Спасибо @AViIgnatov
#rdbms #mq #transactions
Очереди (очереди не равно топики Kafka) есть в Oracle https://docs.oracle.com/en/database/oracle/oracle-database/19/adque/aq-introduction.html
И они поддерживают общие транзакции с таблицами.
Также у Oracle есть шлюз для связывания внутренних и внешних очередей https://docs.oracle.com/en/database/oracle/oracle-database/21/adque/messaging_gateway.html
Аналогично для MSSQL https://learn.microsoft.com/ru-ru/sql/database-engine/service-broker/benefits-of-programming-with-service-broker?view=sql-server-ver16
Спасибо @AViIgnatov
#rdbms #mq #transactions
Oracle Help Center
Advanced Queuing User's Guide
Advanced Queuing (AQ) is a robust and feature-rich message queuing system integrated with Oracle Database. These topics discuss Oracle Database Advanced Queuing (AQ) and the requirements for complex information handling in an integrated environment.
🔥2
Всем привет!
Есть много способов получить данные из БД с помощью JPA:
1) JPQL
2) JPQL Native Query
3) HQL
4) Spring Data JPA Repository
5) Criteria API
6) QueryDSL
...
Предположим, нам нужно вернуть набор строк. Задать параметры запроса можно по-разному, а итог будет один - List или другая коллекция (Collection) с набором данных. Верно? Не совсем)
Если посмотреть на список возвращаемых Spring Data JPA данных https://docs.spring.io/spring-data/jpa/reference/repositories/query-return-types-reference.html#appendix.query.return.types то там можно увидеть много чего интересного. В т.ч. Stream.
А вот пример его использования: https://vladmihalcea.com/spring-data-jpa-stream/
Аналогично можно вернуть Stream и из обычного JPA - см. метод getResultStream, вот пример: https://thorben-janssen.com/jpa-2-2s-new-stream-method-and-how-you-should-not-use-it/
Зачем это может быть нужно?
Во-первых это просто красиво... Шучу. Если вы используете Stream в бизнес-логике - то кажется логичным использовать их и при обращении к БД.
А во-вторых: главная особенность стриминга - равномерная выборка данных. И в каждый момент данных в обработке будет одна запись.
Рассмотрим кейс, когда нужно обработать на клиенте миллион записей.
Ремарка: если у вас такой кейс - подумайте, нет ли проблем в архитектуре. Данные лучше обрабатывать на сервере СУБД. Если все же проблем нет - продолжим)
Так вот, какие у нас варианты:
1) вытащить на клиент миллион записей. Запрос к БД будет один, она выдержит, но с неплохой вероятностью можно убить клиент через Out of Memory.
2) организовать пагинацию, например, вот так: https://www.baeldung.com/spring-data-jpa-iterate-large-result-sets. Данных на клиенте в моменте не много, по размеру страницы, но запросов к БД ... тысяча.
3) использовать стримы. Запрос к БД один, данных на клиенте немного. Не обязательно одна запись, но в любом случае немного, детали ниже.
К слову, стриминг по БД с JPA аналогичен перемещению курсора по ResultSet в JDBC. С накладными расходами и плюшкам, которые дает сессия JPA, конечно.
И про объем данных на клиенте. Казалось бы - вытаскиваем записи поштучно. Но если не указать fetch size - объём предварительной выборки - для некоторых СУБД Hibernate вытащит на клиента все данные за раз, и мы вернемся к варианту 1 (((
#jpa #java_streams #rdbms
Есть много способов получить данные из БД с помощью JPA:
1) JPQL
2) JPQL Native Query
3) HQL
4) Spring Data JPA Repository
5) Criteria API
6) QueryDSL
...
Предположим, нам нужно вернуть набор строк. Задать параметры запроса можно по-разному, а итог будет один - List или другая коллекция (Collection) с набором данных. Верно? Не совсем)
Если посмотреть на список возвращаемых Spring Data JPA данных https://docs.spring.io/spring-data/jpa/reference/repositories/query-return-types-reference.html#appendix.query.return.types то там можно увидеть много чего интересного. В т.ч. Stream.
А вот пример его использования: https://vladmihalcea.com/spring-data-jpa-stream/
Аналогично можно вернуть Stream и из обычного JPA - см. метод getResultStream, вот пример: https://thorben-janssen.com/jpa-2-2s-new-stream-method-and-how-you-should-not-use-it/
Зачем это может быть нужно?
Во-первых это просто красиво... Шучу. Если вы используете Stream в бизнес-логике - то кажется логичным использовать их и при обращении к БД.
А во-вторых: главная особенность стриминга - равномерная выборка данных. И в каждый момент данных в обработке будет одна запись.
Рассмотрим кейс, когда нужно обработать на клиенте миллион записей.
Ремарка: если у вас такой кейс - подумайте, нет ли проблем в архитектуре. Данные лучше обрабатывать на сервере СУБД. Если все же проблем нет - продолжим)
Так вот, какие у нас варианты:
1) вытащить на клиент миллион записей. Запрос к БД будет один, она выдержит, но с неплохой вероятностью можно убить клиент через Out of Memory.
2) организовать пагинацию, например, вот так: https://www.baeldung.com/spring-data-jpa-iterate-large-result-sets. Данных на клиенте в моменте не много, по размеру страницы, но запросов к БД ... тысяча.
3) использовать стримы. Запрос к БД один, данных на клиенте немного. Не обязательно одна запись, но в любом случае немного, детали ниже.
К слову, стриминг по БД с JPA аналогичен перемещению курсора по ResultSet в JDBC. С накладными расходами и плюшкам, которые дает сессия JPA, конечно.
И про объем данных на клиенте. Казалось бы - вытаскиваем записи поштучно. Но если не указать fetch size - объём предварительной выборки - для некоторых СУБД Hibernate вытащит на клиента все данные за раз, и мы вернемся к варианту 1 (((
#jpa #java_streams #rdbms
Vlad Mihalcea
The best way to use Spring Data JPA Stream methods - Vlad Mihalcea
Learn what is the best way to use Spring Data JPA Stream query methods to avoid prefetching all the data in MySQL and PostgreSQL.
🔥3
Можно ли засунуть PostgreSQL в облако?
Когда мы говорим о БД в облаке - обычно говорят о специально созданных для облака noSQL хранилищах.
Как пример можно привести YaDB и Amazon DynamoDB.
Их главные плюсы:
1) managed storage - администрирование идет в комплекте с облаком, неотъемлемая фича облака
2) возможность горизонтального масштабирования
Значит ли это, что старые добрые реляционные БД не попадут в облако и станутся в прошлом?
Нет.
На самом деле я уже об этом писал - https://t.me/javaKotlinDevOps/257
Существуют Azure Cosmos DB for PostgreSQL и Aurora PostgreSQL.
Это проприетарные решения под конкретное облако.
В связи с этим возникает два вопроса:
1) есть ли opensource решения?
2) как вообще удалось затащить PostgreSQL в облако?
Ответ на первый вопрос - да, но детали будут ниже.
А на второй - вспомним, как работает горизонтальное масштабирование в облаке для хранилищ.
Собственно хранилище - объектная файловая система, совместимая с S3 API - в любом облаке есть.
Это storage уровень. У него малая нагрузка на процессор, но большая I/O нагрузка на дисковую систему.
Еще у БД есть движок, рассчитывающий планы выполнения запросов и собственно их выполняющий. Это compute часть. Ей в теории хранилище вообще не нужно, а нужны CPU и RAM.
Т.е. compute часть является stateless, а этом значит ее можно быстро масштабировать с 0 до бесконечности. Ну не бесконечности конечно, а до свободного объема кластера. Учитывая, что тот же PostgreSQL написан на C - подыматься без данных он должен быстро.
Собственно, остается вопрос - позволяет ли PostgreSQL разделять compute и storage? И исходя из предыдущей информации - да, позволяет.
Например, есть https://www.orioledb.com/ Это storage движок для PostgreSQL, исправляющий несколько косяков в базовой архитектуре PostgreSQL в реализации MVCC (многоверсионности). Но это еще не облачное решение, оно позволяет эффективнее использовать ресурсы конкретного сервера. compute и storage все еще на одном сервере.
Но если как compute оставить движок PostgreSQL, а storage разнести по разным серверам(кластерам, зонам доступности) - мы получим облачное решение.
Самый известный opensource вариант - Neon, вот хорошая статья о нем:
https://habr.com/ru/companies/arenadata/articles/927464/
Если всмотреться в архитектуру https://habrastorage.org/r/w1560/getpro/habr/upload_files/30f/688/639/30f688639ad82b12c41b3c7928529d0a.jpg
то там все чуть сложнее, чем я описал выше.
А именно: storage слой - это не просто объектное хранилище S3.
Есть еще два уровня: safekeepers и pageservers.
Чтобы понять, зачем они нужны, следует вспомнить, что PostgreSQL хранит данные дважды:
1) в виде страниц (pages) на диске - слепок текущего состояния
2) и write-ahead logging (WAL) - append-only лог изменений, по которому восстановить состояние БД в любой момент времени.
safekeepers принимают WAL лог от compute node и сохраняют его на нескольких узлах (SSD диски) с соблюдением кворума, т.е. гарантий отказоустойчивости https://neon.com/blog/paxos.
Если safekeeper падает - запросы перенаправляются на другой узел. Но число safekeeper фиксированное, но благодаря кворуму падение какой-то части узлов система выдержит.
pageservers - получают WAL лог от safekeeper и преобразуют его в формат страниц PostgreSQL. После чего сохраняют все это - WAL и страницы с данными - в S3. pageservers тоже имеют SSD диски и являются кэширующим слоем перед S3. При падении конкретного pageserver - трафик переключается на резервный с некой задержкой.
Итого мы имеем:
1) "бесконечное" масштабирование объектного хранилища S3
2) ограниченное размером кластера масштабирование compute nodes
3) фиксированное число safekeepers и pageservers, что не является узким звеном в первом приближении, но требует понимания целевой нагрузки на чтение и запись.
Итого: традиционные СУБД не сдаются) Победит сильнейший)
#rdbms #cloud #nosql
Когда мы говорим о БД в облаке - обычно говорят о специально созданных для облака noSQL хранилищах.
Как пример можно привести YaDB и Amazon DynamoDB.
Их главные плюсы:
1) managed storage - администрирование идет в комплекте с облаком, неотъемлемая фича облака
2) возможность горизонтального масштабирования
Значит ли это, что старые добрые реляционные БД не попадут в облако и станутся в прошлом?
Нет.
На самом деле я уже об этом писал - https://t.me/javaKotlinDevOps/257
Существуют Azure Cosmos DB for PostgreSQL и Aurora PostgreSQL.
Это проприетарные решения под конкретное облако.
В связи с этим возникает два вопроса:
1) есть ли opensource решения?
2) как вообще удалось затащить PostgreSQL в облако?
Ответ на первый вопрос - да, но детали будут ниже.
А на второй - вспомним, как работает горизонтальное масштабирование в облаке для хранилищ.
Собственно хранилище - объектная файловая система, совместимая с S3 API - в любом облаке есть.
Это storage уровень. У него малая нагрузка на процессор, но большая I/O нагрузка на дисковую систему.
Еще у БД есть движок, рассчитывающий планы выполнения запросов и собственно их выполняющий. Это compute часть. Ей в теории хранилище вообще не нужно, а нужны CPU и RAM.
Т.е. compute часть является stateless, а этом значит ее можно быстро масштабировать с 0 до бесконечности. Ну не бесконечности конечно, а до свободного объема кластера. Учитывая, что тот же PostgreSQL написан на C - подыматься без данных он должен быстро.
Собственно, остается вопрос - позволяет ли PostgreSQL разделять compute и storage? И исходя из предыдущей информации - да, позволяет.
Например, есть https://www.orioledb.com/ Это storage движок для PostgreSQL, исправляющий несколько косяков в базовой архитектуре PostgreSQL в реализации MVCC (многоверсионности). Но это еще не облачное решение, оно позволяет эффективнее использовать ресурсы конкретного сервера. compute и storage все еще на одном сервере.
Но если как compute оставить движок PostgreSQL, а storage разнести по разным серверам(кластерам, зонам доступности) - мы получим облачное решение.
Самый известный opensource вариант - Neon, вот хорошая статья о нем:
https://habr.com/ru/companies/arenadata/articles/927464/
Если всмотреться в архитектуру https://habrastorage.org/r/w1560/getpro/habr/upload_files/30f/688/639/30f688639ad82b12c41b3c7928529d0a.jpg
то там все чуть сложнее, чем я описал выше.
А именно: storage слой - это не просто объектное хранилище S3.
Есть еще два уровня: safekeepers и pageservers.
Чтобы понять, зачем они нужны, следует вспомнить, что PostgreSQL хранит данные дважды:
1) в виде страниц (pages) на диске - слепок текущего состояния
2) и write-ahead logging (WAL) - append-only лог изменений, по которому восстановить состояние БД в любой момент времени.
safekeepers принимают WAL лог от compute node и сохраняют его на нескольких узлах (SSD диски) с соблюдением кворума, т.е. гарантий отказоустойчивости https://neon.com/blog/paxos.
Если safekeeper падает - запросы перенаправляются на другой узел. Но число safekeeper фиксированное, но благодаря кворуму падение какой-то части узлов система выдержит.
pageservers - получают WAL лог от safekeeper и преобразуют его в формат страниц PostgreSQL. После чего сохраняют все это - WAL и страницы с данными - в S3. pageservers тоже имеют SSD диски и являются кэширующим слоем перед S3. При падении конкретного pageserver - трафик переключается на резервный с некой задержкой.
Итого мы имеем:
1) "бесконечное" масштабирование объектного хранилища S3
2) ограниченное размером кластера масштабирование compute nodes
3) фиксированное число safekeepers и pageservers, что не является узким звеном в первом приближении, но требует понимания целевой нагрузки на чтение и запись.
Итого: традиционные СУБД не сдаются) Победит сильнейший)
#rdbms #cloud #nosql
Telegram
(java || kotlin) && devOps
Всем привет!
Есть такой интересный вопрос - можно ли поместить СУБД в облако?
Если отвечать на него строго технически - да, можно, для этого в k8s есть специальные типы объектов - StatefulSet https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/…
Есть такой интересный вопрос - можно ли поместить СУБД в облако?
Если отвечать на него строго технически - да, можно, для этого в k8s есть специальные типы объектов - StatefulSet https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/…
👍1
Бесконечный PostgreSQL
В SQL есть такая штука, как подзапросы.
Пример:
Но конкретно в PostgreSQL у подзапросов есть целых 4 альтернативы:
1) CTE (Общее Табличное Выражение)
2) VIEW
3) MATERIALIZED VIEW
4) TEMPORARY TABLE
Все они отличаются от подзапросов тем, что позволяют переиспользование.
И практически все - кроме обычного VIEW - материализуются, т.е. сохраняют результат на диск.
Есть отличия во времени жизни. CTE живут в рамках запроса, временные таблицы - сессии, а VIEW - до удаления. Поэтому VIEW позволяют навешивать права доступа.
Детали как обычно в статье: https://habr.com/ru/articles/855694/
Также рекомендую почитать комменты к статье, там важные дополнения:
- CTE тоже могут материализоваться как и VIEW, но этим сложнее управлять. А наличие или отсутствие материализации играет роль если в выборке есть динамически вычисляемые столбцы - например, генерация uuid, текущая дата или просто random.
- про временные таблицы важно помнить, что они живут только в рамках текущей сессии (соединения). Поэтому при работе с пулом коннектов, т.е. практически всегда, ими пользоваться не стоит.
Ну и еще один важный момент - материализация = сохранение текущего состояния на диск. Данные обновляться не будут!
Меня удивило существование CTE. Хотя если поискать - они в том или ином виде существуют во всех основных СУБД. Даже в SQLite)
#rdbms #postgresql
В SQL есть такая штука, как подзапросы.
Пример:
SELECT column1, column2
FROM table_name
WHERE column1 IN (
SELECT column1
FROM another_table
WHERE condition
);
Но конкретно в PostgreSQL у подзапросов есть целых 4 альтернативы:
1) CTE (Общее Табличное Выражение)
2) VIEW
3) MATERIALIZED VIEW
4) TEMPORARY TABLE
Все они отличаются от подзапросов тем, что позволяют переиспользование.
И практически все - кроме обычного VIEW - материализуются, т.е. сохраняют результат на диск.
Есть отличия во времени жизни. CTE живут в рамках запроса, временные таблицы - сессии, а VIEW - до удаления. Поэтому VIEW позволяют навешивать права доступа.
Детали как обычно в статье: https://habr.com/ru/articles/855694/
Также рекомендую почитать комменты к статье, там важные дополнения:
- CTE тоже могут материализоваться как и VIEW, но этим сложнее управлять. А наличие или отсутствие материализации играет роль если в выборке есть динамически вычисляемые столбцы - например, генерация uuid, текущая дата или просто random.
- про временные таблицы важно помнить, что они живут только в рамках текущей сессии (соединения). Поэтому при работе с пулом коннектов, т.е. практически всегда, ими пользоваться не стоит.
Ну и еще один важный момент - материализация = сохранение текущего состояния на диск. Данные обновляться не будут!
Меня удивило существование CTE. Хотя если поискать - они в том или ином виде существуют во всех основных СУБД. Даже в SQLite)
#rdbms #postgresql
Хабр
СTE, подзапрос или представление?
Здравствуйте, дорогие друзья! Сегодня мы рассмотрим различные подходы, которые разработчики используют для работы с данными в БД. В современном мире разработки, где информация становитесь все больше и...