19 February 2018

Рассуждение на тему, какую базу данных выбирать

MySQLNoSQLMongoDBDatabase Administration

Эта статья для вас, если вы:


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

Моя статья не для вас, если вы:


  • хорошо умеете готовить свою любимую БД, оптимизировать индексы, настраивать и всякое такое;
  • имеете в штате хорошего специалист, который сможет аргументировано выбрать нужный вашему проекту вариант. специалист должен быть действительно хорошим, а не «экспертом на диване»;
  • обслуживаете проект с так называемым «big data», то есть у вас огромные базы, десятки или сотни серверов в кластере и всякое такое — ну у вас как бы должен быть в штате один или несколько специалистов.

О чем пойдет речь в статье?


Я разберу в своей статьи некоторые типичные и не очень варианты выбора баз данных, а если быть более точным — подходы к выбору. Когда следует остановится на том, что используют большинство, а когда можно и задуматься над новым и неизведанным. Я опишу СУБД MySQL, PostgreSQL, MongoDB, Redis, CouchDB/PouchDB и упомяну о Aerospike с Tarantool, парочку других — но в некоторых моментах конкретный выбор не настолько принципиален. Надо понимать, что лучше изначально правильно спроектировать структуру данных, чем выбрать СУБД, а потом уже пытаться придумывать, что в ней собственно хранить.
Итак, начнем.

Небольшие отступления:


  1. Мои выкладки не истина в последней инстанции. Какие-то выводы я делал на основе реального использования, какие-то на основе информации в интернете, обсуждения с другими людьми. Некоторые выводы сделаны на основе реальных задач, а некоторые в чисто теоретических идеях. Вся эта информация есть в том или ином виде на просторах интернета, но достаточно разрознена, я же постараюсь компактно описать в одном месте.
  2. Я рассматриваю только те продукты, которые на момент написания статьи активно развиваются и в то же время стабильно существуют в течении длительного времени. Опять же, на мой взгляд, одним из условий выбора чего-либо для своего проекта — чтобы продукт был достаточно стабильный, рабочий, имел большое и хорошо развитое сообщество, его использование не сопряжено с многодневными танцами с бубном и т.п. И что немаловажно — должна быть возможность официально воспользоваться коммерческой поддержкой и получить тем самым гарантии от разработчика. Следует учитывать, что есть множество других вариантов, но они либо сырые и для их сопровождения в проекте придется прикладывать дополнительные и нерациональные усилия. Либо гораздо менее успешны или популярны.
  3. Я с удовольствием почитаю ваше мнение в комментариях. И об описанных базах данных и не только. И не только я, думаю многим будет интересно почитать аргументированное мнение о какой либо базе данных.
  4. Самое важное и еще раз — здесь не пойдет речь про крупные проекты. В таких проектах обычно уже есть свой архитектор или знающий человек и достаточно средств, чтобы обеспечить оптимальный выбор. Хотя кто знает, может мои выкладки и им пригодятся.

Теперь давайте зададим себе вопросы:


  • Насколько вы консервативны, хотите и любите ли вникать во что-то новое?
  • Хотите не думать или наоборот хотите вникнуть досконально в устройство базы данных?
  • Насколько хорошие программисты в вашей команде, смогут ли они грамотно составить структуру БД или они уже являются отличными специалистами по какой-то одной СУБД?

Ответили? Точно? Тогда я перечислю СУБД и опишу в каком случае рекомендуется обратить на них внимание.

MySQL / MariaDB

Народная СУБД или «must have», есть практически на любом хостинге. Простая в установке, работает нормально без особых настроек. При должном подходе может гибко настраиваться под ваши нужды. Но есть и подводные камни, в некоторые случаях она будет тем самым узким горлышком и ваш проект будет тормозить, как бы вы не тюнинговали СУБД и структуру данных.
MySQL для вас, если:

— вы консерватор и не хотите вникать в настройки СУБД, просто поставили и работает (ну или на хостинге используете то, что дают);
— вы консерватор же, значит мыслите структурно, таблично. MySQL справится;
— в любом языке программирования, фреймворке, CMS, CMF и так далее и тому подобное — есть интеграция с MySQL.
— вы новичОк и вам нужна СУБД для управления структурными данными, желательно небольшими (до 1 — 2 гигабайт).

Минусы? Их есть и вам следует выбрать другую СУБД, если увидите важное.

— посредственная производительность. Действительно низкая, как не тюнингуй. даже кластер не поможет особо (его еще настроить надо, ага, те еще танцы с бубном). Речь о цифрах порядка 20 МБайт/сек. Из личного опыта, на SSD дисках при таком потоке MySQL упирался в свой предел, не справлялся и тормозил, причем сервис настраивался несколько лет, использовались оптимальные для нагрузки настройки. Из коробки конфигурацию, думаю будет еще меньше планку иметь;
— изменение структуры данных может быть довольно трудоемким процессом, особенно при большом количество связей между данными в разных таблицах и даже при простом добавлении полей;
— чувствительность к нестабильности сервера. Особенно это влияет при использовании XtraDB от Percona. Если неправильно завершить MySQL, можно настолько поломать таблицы и базы данных, что восстановить можно будет только из полного бекапа, конечно, если вы их регулярно делаете. И поверьте, это случается всегда в самый неожиданный момент. Есть инструменты, которые в несложных ситуациях помогут восстановить работоспособность, но они не панацея. В последних и актуальных версиях активно борются с этим, заявлена гораздо лучшая стабильность и надежность.

PostgreSQL

Своего рода мастодонт, очень старая и грамотная СУБД. Она почти как MySQL, только лучше. Но надо уметь готовить и настраивать. По мнение многих, очень стабильная СУБД, ее практически невозможно уронить, порушить таблицы как в MySQL. И это может быть для вас решающим фактором при выборе.

PostgreSQL для вас, если:

— вы консерватор (понимаю повторяюсь, но так и есть) и нужно надежное хранилище;
— вы или ваш специалист умеете настроить и использовать PostgreSQL;
— вам нужны хорошо структурированные данные, но с некоторой гибкости в схеме данных (JSON/BJSON);
— при помощи сторонних библиотек просто и удобно расширяться в кластеры и делать шардинг таблиц. И все это действительно работает.

А минусов как то вот не особо описывать… Справедливости ради, особо практики не имел, в основном сужу по рассказам знакомых:

— необходимость опыта работы с этой СУБД, чтобы приготовить ее хорошо. Иначе лучше взять MySQL или прочитать дальше;
— система авторизации по умолчанию может вызвать затруднения при использовании или настройке, далеко не всем нравится, некоторые даже очень опытные разработчики до сих пор не до конца понимают как оно там работает.

MongoDB

О, сколько копий до сих пор ломается — SQL или NoSQL… Но все же в некоторых случаях MongoDB справляются с задачей гораздо лучше, чем MySQL или PostgreSQL. Например, реальный случай, свидетелем которого я был — сбор и обработка статистики по хостингу (нагрузка на CPU, i/o, память и т.п.) — MySQL не справился от слова вообще. MongoDB справился без особых проблем. База данных достигает объема в 200-300 ГБайт, поток данных достигает 100 и более МБайт/сек. Показательно, на мой взгляд.

MongoDB для вас, если:

— у вас нет четкой, заранее описанной структуры данных или вы предполагаете, что состав данных может потом сильно изменится (конечно это можно делать в SQL, но надо мыслить другими понятиями, поменять то можно, но вопрос насколько это будет трудоемко);
— у вас планируется довольно серьезный объем данных (десятки или даже сотни ГБ), определить это даже на этапе ТЗ можно;
— вам просто хочется NoSQL, модно же;
— легко установить и попробовать, работает нормально без особых настроек. А если углубится, изучить, то настроить можно очень многое.

Минусы тоже есть.

— Нет простых транзакций. По крайней мере в том, классическом виде, какие они есть в MySQL/PostgreSQL. При добавлении множества данных, которые зависят друг от друга, могут быть определенные трудности, которые придется решать самостоятельно на уровне кода. Ну то есть вы можете и не столкнутся конечно, но…;
— связность данных практически отсутствует. Сразу приходит на ум, постоянно упоминают JOIN из SQL — вот этого по сути нет. Хотя, если быть более точным, то надо просто мыслить другими категориями;
— нужно перестраивать мышление именно под NoSQL. иначе будет сложно сопровождать — то есть хороший программист (точнее архитектор ПО) обязателен в дальнейшем.

Redis

Чаще всего эту СУБД используют в качестве кеширующего слоя для работы с данными из другой, более медленной СУБД. Лучшая замена memcached, если вам это что-то скажет. Редко, но все же может использоваться в качестве самостоятельно БД для данных. При этом Redis умеет разные типы данных, в том числе списки, очереди, умеет Pub/Sub, а еще очень просто работать с TTL (время жизни ключа). Работает в памяти, очень быстрая, умеет сохранять данные на диске, причем с поддержкой дозаписи (гораздо меньше нагружает диск) и загружать при запуске. Почти сказка.

Redis для вас, если:

— объем данных небольшой и очень простая схема, укладывающая в шаблон «ключ=значение»;
— простая реализация репликации Master — Slave. Действительно очень простая настройка, достаточно добавить в конфиг сервера указания на мастера, запустить Redis Server и данные уже реплицируются. Хотя, наверное, следует уточнить, что настроить гибкую репликацию (частичную) вряд ли получится;
— нужен Pub/Sub (очереди). Справедливости ради следует сказать, что есть отдельные системы Pub/Sub, реализующие помимо этого паттерна и другие. Redis реализует это достаточно элегантно и просто, вполне возможно вам другие не понадобятся;
— нужен кеш для более медленной СУБД или просто хотите не задумываться о скорости работы СУБД с оглядкой на ее объем. Примером может послужить сайт на Drupal, с основной базой данных в MySQL и кешем в Redis. Проводил тесты ради интереса обычным ab, скорость отдачи контента может увеличится в разы. На обычном Apache + Redis + mod_php можно достичь сравнимой производительности с Nginx + php-fpm, а если к Nginx добавить Redis…

Минусы тоже есть, как же без них.

— объем данных не должен превышать объем свободного ОЗУ на вашем сервере (на самом деле может, но тогда все они будут уходить в swap, сильно замедлять работу, в общем лучше избегать);
— в угоду производительности присутствует довольно слабая сохранность данных. То есть вполне может произойти такое, что данные добавили, а после рестарта их нет. Включение AOL (append of file) немного сглаживает ситуацию, но тогда загрузка с диска будет довольно длительной;
— транзакции и связанные данные не то, чтобы умеет. Если точнее — есть Pipeline и Multi/Exec, но это все таки не совсем транзакция в классическом понимании;
— до сих пор не умеет нормально кластер и шардинг. Нормальной реализации до сих пор нет.

Конечно можно напрячься и сделать что-то похожее на кластер при помощи специального скрипта, но на мой взгляд выглядит это довольно кривовато и неоптимально.

Альтернативы


Из личного опыта и блуждания по интернету, изучения разных статей, обзоров я встречал несколько различных вариантов, которые можно применить в случае, если вас что-то не устроило в предыдущих вариантах. Итак, встречайте еще несколько интересных проектов.

IBM Lotus Domino/Notes

На мой взгляд ярчайший пример успешного коммерческого проекта СУБД концепции NoSQL. Хотя подозреваю, что успех скорее не в его NoSQL, а в наличии полноценного сервера приложений с встроенным редактором кода и интерфейса к базе. Решение очень зрелое, существует на рынко довольно давно и поддерживается гигантом IBM — ну то есть очень даже круто. Лично участвовал в разработке двух разных систем электронного документооборота на его базе, а также сопровождал некоторые критично важные приложения в банке. Кстати, несмотря на платную политику распространения, мало кто знает, но его можно бесплатно скачать для изучения.

CouchDB

Хотите хранить документы разной структуры (ну как MongoDB, типа), но у вас нет для приложения адаптера или не хотите лишних зависимостей? CouchDB работает через http, имеет встроенный веб-сервер, обменивается в JSON. Очень удобно. Кстати умеет транзакции и можно подписываться на изменения данных. Но это не точно.

PouchDB

Это очень интересный проект, как бы аналог CouchDB, но более приземленный, встраиваемый вариант. Встроили в приложение, работает как локальная база данных, но умеет настраиваемую репликацию с CouchDB или PouchDB Server (на базе ExpressJS). PouchDB на самом деле скорее прослойка, где снаружи вы работаете с единым API, CouchDB-подобным, но внутри может быть совсем разные СУБД — и SQLite и LevelDB и браузерная база данных и MongoDB и даже MySQL. Очень пригодится, если вы делаете распределенное приложение, где обмен данными важен, но связь с сервером может быть нестабильной или эпизодической.

Aerospike

На мой взгляд отличная замена Redis в плане key/value БД. Умеет транзакции, умеет сохранность данных, умеет большой объем данных (превышающий объем доступной ОЗУ). Правда нет Pub/Sub и каких-то особых структур данных, но работает быстро и хорошо. Пожалуй единственным недостатком это слабая популярность по сравнению с Redis. Непонятно кстати почему…

Apache Cassandra

Спроектирована и работает как распределенная NoSQL СУБД для больших данных. Данные хранит в виде семейства столбцов, что сперва может изменить кардинально подход к разработке приложения. Но после ломки мышления вполне может оказаться, что это именно то, что вам надо. Заявлено простое добавление узлов на лету, высокая отказоустойчивость при выходе одного из узлов. В теории можно использовать на небольших проектах, но выглядеть будет наверное, как будто микроскопом забивать гвозди.

Tarantool

Замечательный проект от Mail.Ru. Что-то среднее между Redis/Aerospike и MongoDB… Хотя по моему сами разработчики до сих пор затрудняются провести аналогии :). Его надо уметь, а если быть более точным хотеть готовить. И речь не про настройку, а про постоянную подгонку под разработку новых версий Tarantool. Нужно хотеть вникать во внутреннее устройство этого проекта, постоянно изучать изменения его API и документации, все время подгонять код приложения под изменения. А если вы еще и хотите поучаствовать в процессе разработки, пообщаться с разработчиками в чате — тогда тем более это для вас.

А вот теперь как бы и все.

Да, я упомянул далеко не все СУБД (если смотреть на этом сайте, то там перечислено 253 названия). Надеюсь вы и не думали, что я их все перечислю?

Возможно в описании той или иной СУБД я допустил неточность и не упомянул нечто важное. Такое очень даже возможно и если так — напишите в комментариях, я с интересом почитаю.
Надеюсь мои выводы окажутся полезными и интересными.

UPD1: По поводу отказоустойчивости MySQL. Вы все правы. Я не заявляю, что InnoDB нестабильна, я лишь упомянул, что ситуация это возможна. И если она произойдет, то восстановить работоспособность никак нельзя будет, только начисто восстанавливать все целиком из бекапа. Именно об этом речь, а не о том, что вы решили будто я считаю ее нестабильной. По реальному примеру, на серверах у нас такое произошло за последний год 2 или 3 раза. На разных серверах. На сервере несколько сотен баз с разной нагрузкой, объемов и т.п. Это не значит, что у вас MySQL будет падать регулярно на виртуалке с одним-двумя сайтами, совсем не об этом речь. Как то так.
Tags:nosqlmongodbrediscouchdbpouchdbmysqlpostgresqlсубд
Hubs: MySQL NoSQL MongoDB Database Administration
+2
70k 148
Comments 71