SQL или NoSQL: как я выбирал базу для нагруженного проекта

Olga.Belov

New member
Полтора года назад я запускал небольшой сервис аналитики, который неожиданно выстрелил: за три месяца нагрузка выросла с пары тысяч запросов в сутки до восьми миллионов. И первым вопросом, который встал передо мной в три часа ночи, был вовсе не про архитектуру или железо, а про то, куда всё это складывать. SQL или NoSQL — я перечитал, наверное, десяток статей на эту тему и ни в одной не нашёл ответа, который подошёл бы именно моему проекту.

Начинал я, как и большинство, с классики: PostgreSQL, аккуратная схема, внешние ключи, транзакции. И знаете что? Это было правильное решение. Первые месяцы я вообще не думал о базе — она просто работала, а я занимался продуктом. Реляционная модель отлично легла на данные: пользователи, события, отчёты, подписки. Когда я слышу, что SQL устарел и не тянет высокие нагрузки, я вспоминаю, сколько лет и сил ушло бы у меня на то, чтобы вручную реализовать то, что здесь давалось бесплатно.

Проблемы начались там, где я их не ждал. Основной поток событий писался в одну таблицу, и когда счётчик пошёл на десятки тысяч вставок в секунду, база начала задыхаться. Не потому что PostgreSQL плохой, а потому что я сделал выбор в пользу удобства, а не в пользу паттерна доступа. Индексы разбухали, автовакуум не успевал, а горячие строки превращались в узкое горлышко. Вот тут я впервые всерьёз пошёл смотреть в сторону NoSQL.

Первое, что я попробовал, — это вынести поток неструктурированных логов в документную базу, а агрегаты и справочники оставить в реляционной. И это сработало. Схема без жёстких ограничений позволила писать быстрее и проще масштабироваться по узлам, а аналитика по-прежнему жила в SQL, где ей и место. Отдельная история — кэш: прослойка в памяти перед базой сняла с меня больше нагрузки, чем любой переход на другую СУБД. Если честно, именно кэш, а не выбор модели хранения, дал основной прирост.

К чему я всё это веду. Спор SQL против NoSQL — во многом спор о том, какая у вас нагрузка и как вы читаете данные. Если у вас сложные связи, отчёты, транзакции и целостность важнее скорости записи, реляционная база почти всегда выигрывает, и не надо стесняться её выбирать. Если у вас поток однотипных событий, огромные объёмы, гибкая схема и горизонтальное масштабирование в приоритете — документная или колоночная база будет честнее. А ещё чаще правильный ответ — вообще не выбирать одно, а взять оба и развести их по разным задачам.

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

Сейчас у меня гибридная схема: транзакционное ядро на PostgreSQL, поток событий в документной базе, горячие данные в памяти. И знаете, я ни разу не пожалел, что не стал фанатом ни одного лагеря. Технология — это инструмент под задачу, а не религия, и признать это оказалось самым взрослым решением в моей практике. А теперь вопрос к вам, форумчане: какой опыт выбора базы между SQL и NoSQL был у вас, что в итоге прижилось в проекте и что вы посоветовали бы себе начинающему?
 
Назад
Вверх