(java || kotlin) && devOps
366 subscribers
6 photos
1 video
7 files
332 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
3) нет никаких нормальных форм, дублирование данных не то что допустимо, а, наоборот, скорее является правилом. Т.е. если у нас есть агрегат клиента и агрегат заказа, то адрес доставки просто задублируется в обоих записях. Отсюда встает проблема обновления.
Решения:
а) не обновлять, если данные типа истории операций
б) фоновый процесс для обновления

4) ну и еще раз вернемся к термину NoSQL - основным способов доступа к данным является клиентский модуль для вашего языка или REST API, хотя может быть доступно и SQL-подобное API.

На сегодня все, если интересно - пишите, продолжу.

#noSQL #RDBMS
👍3
Всем привет!

В прошлом посте я "забыл" про еще один, возможно ключевой аспект 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 СУБД может возникнуть вопрос - ага, тут у нас ключ-значение, где-то я это уже видел. А, распределенные кэши. Redis, EhCache, Memcached, Hazelcast, Ignite. В чем разница? Это тоже NoSQL?
Если посмотреть на рейтинг СУБД https://db-engines.com/en/ranking - то да, все они там есть. Кстати, хороший сайт, аналог рейтинга Tiobe для языков программирования. Там даже Microsoft Access есть) Сайт хороший, но мне такой критерий определения: СУБД или нет - не очень нравится.
Я бы сказал: критерий отнесения к NoSQL хранилищам в персистентности, а если быть точным - позиционируют ли создатели системы ее как долговременное хранилище данных. Почему это важно? Если разработчики не предполагают, что в их системе можно долго, а в предельном случае вечно хранить данные, то там наверняка не будет необходимых для этого средств. Это могут быть утилиты для резервного копирования, а оно нужно даже при наличии репликации для возможности отката при порче данных из-за программной ошибки\взлома. Или тонких настроек взаимодействия с файловой системой. Или гарантии персистентности при сбое сервера сразу после ответа клиенту об успешной записи, которая (гарантия) обычно обеспечивается предварительной записью в Write Ahead Log (WAL) или лог транзакций. И чего-то еще, что я не знаю т.к. не являюсь DBA.
Redis - вообще говоря это первая NoSQL система, просто ее спроектировали как замену RDBMS еще до того, как появилось понятие NoSQL. Хотя Redis можно использовать как распределенный кэш. Поддерживает все необходимое для долгосрочного хранения данных https://redis.io/docs/management/persistence/
Memcached и EhCache. Это все-таки распределенные кэши с персистентностью, а не NoSQL. Может возникнуть вопрос - EhCache разве распределенный? Уже да - https://www.ehcache.org/documentation/3.1/caching-concepts.html Но судя по описанию архитектуры сервиса - уровень хранения на диске для Ehcache вторичен.
Аналогично Memcached - https://github.com/memcached/memcached/wiki/Extstore По умолчанию хранение на диске выключено. Цель дискового храненения - увеличение процента попадания в кэш.
Hazelcast и Ignite относятся к категории IMDG In-Memory Data Grid. Суть в том, что данные шардированы по разным серверам и есть возможность выполнять вычисления на одном сервере с данными. А это радикально увеличивает быстродействие и дает возможность в онлайне рассчитывать какую-то аналитику, подсказки и спецпредложения для клиента, выявлять фрод и т.д. Также можно сравнить IMDG с хранимыми процедурами в СУБД, которые тоже позволяли ускорить обработку данных, но в отличие от хранимых процедур код здесь написан на стандартных языках программирования.
При этом Hazelcast позиционирует себя как In-memory NoSQL - https://hazelcast.com/use-cases/in-memory-nosql/ В примерах использования в целом говорится о том же - https://hazelcast.com/use-cases/, см. сравнение с Cassandra, а это напомню NoSQL типа "семейство столбцов" - не замена, а способ улучшить производительность Cassandra. К слову - персистентность выключена по умолчанию и доступна только в Enterprise версии https://docs.hazelcast.com/hazelcast/5.2/storage/configuring-persistence
С Ignite интереснее. Есть 3 канала записи на диск - WAL, checkpointing (сброс незафиксированных данных на диск) и собственно запись данных на диск. Первые два должны обеспечивать достаточную надежность при сбоях https://ignite.apache.org/docs/latest/persistence/native-persistence
Себя позиционируют как NoSQL, только с SQL - хорошо звучит)))) - и транзакциями, правда ограниченными https://ignite.apache.org/faq.html
Но с другой стороны я знаю практический кейс, когда кластер Ignite очень долго допиливали и "тюнили" с целью заставить восстанавливаться в приемлемые сроки после сбоя. Прямо очень очень долго. Т.е. необходимый функционал есть, вопрос в отказоустойчивости и падении производительности при сбоях. Так что использовать Ignite как NoSQL хранилище можно, но осторожно, но с обязательным НТ и chaos engineering тестами.

#cache #imdg #nosql #rdbms
👍2
Всем привет!

Снова про NoSQL. NoSQL хорошо масштабируется, дает гибкую схему данных, но при этом мы теряем в гибкости запросов. В частности нельзя агрегировать данные - GROUP BY. Там же данные из разных агрегатов, собирать нужно со всех серверов кластера. Так? Нет)
Если RDBMS агрегирует можно сказать "просто" - по одному серверу, то NoSQL системы работают хитрее. Они используют технику MapReduce, автором которой является Google https://ru.wikipedia.org/wiki/MapReduce. Я опишу архитектуру MapReduce на примере Riak, в остальных хранилищах, подозреваю, алгоритм похож.
Для начала нужно задать 2 метода на одном из стандартных языков программирования: Map и Reduce. Их можно задавать при каждом запросе к БД, где нужна агрегация или прихранить на сервере, тогда получится аналог хранимой процедуры. Пусть клиенсткий запрос пришел на один из серверов кластера. Этот сервер пересылает его на другие сервера. Вначале выполняется метод Map на всех "строках" требуемой сущности, преобразуя строку в какое-то представление. Например, если взять агрегат Count - строка преобразует в 1. Код выполняется на параллельно на всех серверах. Далее на каждом сервере выполняется второй метод - reduce, который суммирует все результаты Map. Далее все результаты reduce возвращаются на исходный сервер и там снова выполняется reduce. Ответ возвращается клиенту. Если нужно - есть возможность задать условие фильтра, которое отфильтрует строки до передачи их в Map.
Решение IMHO красивое и быстрое. Кажется, на больших данных и сложном агрегировании может работать быстрее, чем в RDBMS за счет распараллеливания. Конечно зависит от агрегата, объема, СУБД.
Вот реализация Riak https://docs.riak.com/riak/kv/latest/developing/app-guide/advanced-mapreduce/index.html
Вот более сложно, в виде конвейера - Mongo https://www.mongodb.com/docs/manual/core/aggregation-pipeline/
Cassandra имеет ряд базовых функций: COUNT, SUM, MAX, MIN, AVG - из коробки, по позволяет создавать User-Defined Aggregates, работающих по тому же принципу: https://cassandra.apache.org/doc/latest/cassandra/cql/functions.html?highlight=aggregate#aggregate-functions

Из минусов - реализации MapReduce у всех разные, некий vendor-lock присутствует. Но учитывая, что API тоже у всех разное - он в любом случае будет)

#NoSQL
👍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
👍1