Руководство по NoSQL для разработчиков

Статья из группы Java Developer
Если вы следите за тенденциями в сферах backend-разработки и Big Data, то, вероятно, уже обратили внимание на шумиху вокруг баз данных NoSQL, характерную для последних лет. Кого-то такой подход к БД вдохновляет, кому-то кажется, что в нём сокрыт какой-то трюк: модели данных в них не такие, как в привычных реляционных базах, интерфейсы программирования приложений непривычны, а приложения зачастую непонятны. Руководство по NoSQL для разработчиков  - 1В этой статье я расскажу, почему они вообще были созданы, эти базы данных NoSQL, какие задачи они решают и почему вдруг необходимо так много различных баз данных. Если вы — новичок в NoSQL, вас может особенно заинтересовать последняя часть статьи, в которой перечисляются базы данных этого типа, которые, по моему мнению, стоит изучить прежде всего, чтобы получить полное представление об этой области.

Зачем нам вдруг нужна новая база данных?

Вы можете недоуменно спросить: а что не так с реляционными базами данных? Дело в том, что они действительно прекрасно работали на протяжении многих лет, но теперь появилась проблема, с которой они больше не могут справиться. Согласно некоторым предсказаниям, в 2018 году человечество будет генерировать 50000 гигабайт данных в секунду. Это колоссальный объем данных! Его хранение и обработка представляет собой серьезный инженерный вызов. А ещё страшнее то, что этот объем постоянно растёт. Как оказалось, реляционные базы данных плохо приспособлены к работе с действительно большими объемами данных. Они спроектированы для работы на одной машине, и если вы хотели бы обрабатывать бОльшее количество запросов, то единственный вариант — купить компьютер с большим количеством оперативной памяти и более мощным процессором. К сожалению, количество запросов, которые способна обработать одна машина, ограничено, а для распределённой работы на нескольких машинах нам требуется другая технология баз данных. Конечно, некоторые из читателей в этот момент усмехнутся и скажут, что существует два широко распространенных метода использования нескольких машин в случае реляционной базы данных: репликация и шардинг. Оно-то так, но этих методов недостаточно, чтобы справиться с нашими задачами. Репликация чтения – методика, при которой каждое обновление базы данных распространяется на другие машины, которые могут обрабатывать только запросы на чтение. В этом случае все изменения выполняются одним сервером, называемым ведущим узлом, в то время как другие сервера, называемые репликами чтения, лишь поддерживают копии данных. Пользователь может читать с любой из машин, но изменять данные лишь через ведущий узел. Это удобный и очень популярный метод, но он позволяет лишь обрабатывать больше запросов на чтение и никак не решает задачу обработки требуемых объемов данных.
Руководство по NoSQL для разработчиков  - 2
На рис.:
Leader (read and write): Ведущий узел (читает и записывает)
Read-replicas (read-only): Реплики чтения (только для чтения)
Шардинг – ещё один популярный подход, при котором используется несколько экземпляров реляционной базы данных. Каждый из них обрабатывает операции записи и чтения для части данных. Если в базе данных хранится, например, информация о покупателях, с помощью шардинга одна машина может обрабатывать все запросы о покупателях, чьи имена начинаются на A, другая – хранить все данные о покупателях, чьи имена начинаются на B, и так далее.
Руководство по NoSQL для разработчиков  - 3
На рис.:
Multi-master (read and write part of data): Несколько ведущих узлов (читающих и записывающих части данных)
Хотя шардинг позволяет записывать больше данных, управление такой базой данных – настоящий кошмар: приходится выравнивать данные по машинам и масштабировать кластер в обе стороны по мере необходимости. Хотя в теории это выглядит просто, правильная реализация – весьма сложная задача.

Можно ли усовершенствовать реляционные базы данных?

Думаю, вы уже поверили в то, что реляционные базы данных не лучшим образом приспособлены к генерируемым в современном мире объемам данных. Хотя, возможно, вы всё ещё недоумеваете, почему никто до сих пор не создал "улучшенной" реляционной базы данных, которая могла бы эффективно работать на нескольких машинах. Может показаться, что эта технология просто еще не разработана, и очень скоро появятся распределенные реляционные базы данных. Увы, этого не произойдет. Это невозможно с точки зрения математики, и ничего поделать с этим нельзя. Чтобы понять, почему это так, необходимо обратиться к так называемой теореме CAP (она же теорема Брюера). Её доказали в 1999 году, и она утверждает, что у работающая на нескольких машинах распределенная база данных может обладать следующими тремя свойствами: Согласованностью (Consistency) – в результате любой операции чтения возвращаются результаты последней соответствующей операции записи. Если система согласована, после записи новых данных, прочитать старые, уже перезаписанные, невозможно. Доступностью (Availability) – распределенная система в любой момент может обслужить входящий запрос и вернуть не ошибочный ответ. Устойчивостью к нарушению связности (Partition tolerance) – база данных продолжает отвечать на запросы на чтение и запись даже в случае, когда часть её серверов временно неспособны взаимодействовать друг с другом. Этот временный сбой называется нарушением связности сети и может вызываться множеством фактором, начиная от физических проблем с сетью из-за медленно работающего сервера и заканчивая физическим повреждением сетевого оборудования. Все эти свойства, безусловно, удобны, и нам бы очень хотелось, чтобы база данных сочетала их все. Ни один здравомыслящий разработчик не захочет отказаться от, скажем, доступности, не получив ничего взамен. К сожалению, теорема CAP также утверждает, что одновременное выполнение всех трёх свойств — невозможно. Осознать это может быть непросто, но возможно. Во-первых, если нам нужна распределенная база данных, она обязана быть "устойчивой к нарушению связности". Это даже не обсуждается. Нарушения связности происходят всё время и наша база данных обязана работать, несмотря на это. Теперь давайте поймем, почему мы не можем добиться одновременно согласованности и доступности. Представьте, что у нас есть простая база данных, работающая на двух машинах: A и B. Любой её пользователь может выполнять запись на любую из машин, после чего данные копируются на другую.
Руководство по NoSQL для разработчиков  - 4
Теперь представьте себе, что эти машины временно утратили возможность обмена сообщениями друг с другом, и машина B не может отправлять данные на машину A или получать данные от неё. Если в этот промежуток времени машина B получит запрос на чтение от клиента, у неё есть две возможности:
  1. Вернуть свои локальные данные, даже если они не самые свежие. В этом случае отдается предпочтение доступности (вернуть хоть какие-то данные, даже устаревшие).
  2. Вернуть ошибку. В этом случае отдается предпочтение согласованности: клиент не получит устаревшие данные, но и не получит вообще никаких.
Руководство по NoSQL для разработчиков  - 5
На рис.:
Network partition: Нарушение связности сети
Реляционные базы данных стремятся воплотить свойства "согласованности" и "доступности" одновременно, и, следовательно, не могут работать в распределенной среде. Попытка реализовать все возможности реляционной базы данных в распределенной системе окажется или нереалистичной, или просто невыполнимой. С другой стороны, базы данных NoSQL, придают основное значение масштабируемости и производительности. В них обычно отсутствуют такие "базовые" возможности, как соединения и транзакции, а модель данных оказывается совсем другой, возможно, в чем-то даже ограничивающей. Всё это дает возможность хранения больших объемов данных и обработки большего числа запросов, чем было возможно когда-либо ранее.

Как базам данных NoSQL удается сочетать согласованность и доступность?

Вам может казаться, что выбрав NoSQL БД, вы всегда будете получать или какие-то устаревшие данные, или ошибку в случае любого сбоя. На практике же, доступность и согласованность — отнюдь не единственные возможные варианты. Существует широкий спектр доступных для вашего выбора вариантов. В реляционных базах данных этих параметров нет, но NoSQL позволяет вам управлять выполнением запросов подобным образом. Так или иначе, они позволяют задавать два параметра при выполнении операций записи или чтения в NoSQL базе данных: W – сколько машин в кластере должно подтвердить сохранение данных при выполнении операции записи. Чем больше число машин, куда вы запишете свои данные, тем легче будет прочитать наиболее свежие данные при следующей операции чтения, но и тем больше времени это займет. R – с какого количества машин вы хотели бы читать данные. В распределенной системе, распространение данных по всем машинам кластера может занять некоторое время, так что на некоторых серверах данные будут актуальными, а другие будут отставать. Чем больше число машин, с которых читаются данные, тем выше шансы прочитать актуальные данные. Рассмотрим практический пример. Если в вашем кластере пять компьютеров, и вы решили записывать данные лишь на один, а затем читать данные с одного случайно выбранного компьютера, то с вероятностью 80% вы прочитаете устаревшие данные. С другой стороны, при этом будет использоваться минимум ресурсов. Так что, если устаревшие данные вас устраивают, это не такой уж плохой вариант. В этом случае параметры W и R равны 1.
Руководство по NoSQL для разработчиков  - 6
С другой стороны, если вы записываете данные на все пять машин в базе данных NoSQL, то можете читать данные с любой машины, и каждый раз гарантированно получите актуальные данные. Выполнение той же операции при большем числе машин займет дольше времени, но если актуальные данные для вас важны, то можно выбрать этот вариант. В этом случае W = R = 5. Каково минимальное количество операций чтения и записи, необходимое для согласованности база данных? Вот простая формула: R + W ≥ N + 1, где N – число машин в кластере. Это значит, что при пяти серверах, можно выбрать или R = 2 и W = 4, или R = 3 и W = 3 или R = 4 и W = 2. В этом случае не имеет значения, на какие машины записываются данные, чтение всегда будет производиться, по крайней мере, с одной машины с актуальными данными.
Руководство по NoSQL для разработчиков  - 7
У других баз данных, например, DynamoDB, ограничения отличаются, и они разрешают лишь согласованные операции записи. Каждый элемент данных хранится на трёх серверах, и при записи любых данных, он записывается на две машины из трех. Но при чтении данных можно выбрать один из двух вариантов:
  1. Cтрого согласованное чтение, при котором данные читаются с двух машин из трёх и всегда возвращаются последние записанные данные.
  2. Чтение, согласованное в конечном счёте, при котором выбирается случайным образом одна машина, с которой читаются данные. При этом, однако, могут временно возвращаться устаревшие данные.

Почему существует так много NoSQL баз данных?

Если вы следите за последними новостями в области разработки программного обеспечения, то наверняка слышали о множестве различных NoSQL баз данных, например, MongoDB, DynamoDB, Cassandra, Redis и многих других. Возможно, вы удивитесь: зачем нужно так много различных NoSQL баз данных? Причина проста: что различные базы данных NoSQL предназначены для решения различных задач. Именно поэтому число конкурирующих баз данных так велико. NoSQL базы данных делятся на четыре основные категории:

Документно-ориентированные базы данных

Эти базы данных предоставляют возможность хранения сложных вложенных документов, в то время как большинство реляционных баз данных поддерживает лишь одномерные строки. Такая возможность может пригодиться во многих случаях, например, при необходимости хранения в системе информации о пользователе с несколькими адресами. При использовании документно-ориентированной базы данных, в подобном случае можно просто хранить сложный объект, включающий массив адресов, в то время как в реляционной базе данных вам пришлось бы создать две таблицы: одну для информации о пользователе, а вторую для адресов. Документно-ориентированные базы данных позволяют сократить разрыв между объектной моделью и моделью данных. Некоторые реляционные базы данных, такие как PostgreSQL, теперь тоже поддерживают документно-ориентированное хранилище, но в большинстве реляционных баз данных эта возможность всё еще отсутствует.

Базы данных типа "ключ/значение"

Базы данных типа "ключ/значение" обычно реализуют простейшую NoSQL-модель. По существу, они предоставляют вам распределенную хэш-таблицу, позволяющую записывать данные по заданному ключу и читать их обратно с его помощью. Базы данных типа "ключ/значение" легко масштабируются и отличаются от других баз данных значительно более низкой задержкой.

Графовые базы данных

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

Столбцовые базы данных

Основное различие между столбцовыми и другими типами баз данных заключается в способе хранения данных на диске. Реляционные базы данных создают по файлу для каждой таблицы и хранят значения для всех строк последовательно. Столбцовые базы данных создают по файлу для каждого столбца ваших таблиц. Такая структура позволяет агрегировать данные и выполнять определенные запросы эффективнее, однако необходимо убедиться, что данные соответствуют ограничениям таких баз данных.

Какую базу данных выбрать?

Выбор базы данных – обычно мучительная проблема, и при таком количестве возможных вариантов может показаться невыполнимой задачей. Хорошая новость состоит в том, что нет нужды выбирать только одну. Вместо создания единого монолитного приложения, реализующего все возможности и имеющего доступ ко всем данным системы, можно воспользоваться еще одним современным паттерном под названием "микросервисы": разбить приложение на набор независимых сервисов. Каждый сервис решает свою узкую задачу, и использует только свою базу данных, которая максимально подходит для решения этой задачи.

Как прикажете всё это выучить?

При таком количестве баз данных, выучить их все может показаться невыполнимой задачей. Хорошая новость: этого делать и не надо. Существует лишь несколько основных типов NoSQL баз данных, и, если разобраться в принципах их работы, разобраться с другими будет намного проще. Также, некоторые NoSQL базы данных используются намного чаще других, так что лучше сосредоточить усилия на наиболее популярных решениях. Вот список чаще всего используемых NoSQL баз данных, на которые, как мне кажется, вам стоит взглянуть:
  1. MongoDB. Вероятно, самая популярная NoSQL база данных на рынке. Если компания не использует в качестве основного хранилища данных реляционную базу данных, то, вероятно, она использует MongoDB. Это гибкое хранилище документов с хорошим набором инструментария. В начале своей "карьеры" у MongoDB была не лучшая репутация, потому что данные в ней в некоторых случаях терялись, но с тех пор её стабильность и надежность намного повысились. Взгляните на этот посвященный MongoDB курс, если хотите узнать больше.

  2. DynamoDB. Если вы используете веб-сервисы Amazon (AWS), вам лучше узнать больше о DynamoDB. Это исключительно надежная, масштабируемая база данных с низкой задержкой, богатым набором возможностей и интеграцией с множеством других сервисов AWS. А самое приятное то, что её не нужно развертывать самостоятельно. Настроить масштабируемый кластер DynamoDB, способный обрабатывать тысячи запросов, можно всего за несколько щелчков мышью. Если это вас заинтересовало, можете взглянуть на вот этот курс.

  3. Neo4j. Самая распространенная графовая база данных. Это масштабируемое и стабильное решение, подходящее для желающих воспользоваться графовой моделью данных. Если хотите узнать больше – начните с этого курса.

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

В 2018-м с NoSQL

NoSQL базы данных – обширная и быстро развивающаяся область. Они позволяют хранить и обрабатывать неслыханные до сих пор объемы данных, но за это приходится платить. В этих базах данных нет многих привычных по реляционным базам данных возможностей, и настроить себя на их использование может оказаться непросто. Но когда вы с ними разберетесь, то сможете создавать масштабируемые распределенные базы данных, способные обрабатывать поразительные объемы запросов на чтение и запись, что может иметь исключительное значение по мере генерации всё больших и больших объемов данных. Оригинал: https://simpleprogrammer.com/guide-nosql-software-developers/
Что еще почитать?

Клёвые оптимизации SQL, не зависящие от стоимостной модели. Часть 1

Как правильно начать разработку под СУБД Oracle

Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
hidden #2039138 Уровень 35
23 сентября 2019
Но можно же репликацию и фрагментацию объединить. Вот есть такой-то список узлов над одним фрагментом бд и так далее.