MAATRIX / Блог / Миф: горизонтальное масштабирование всегда лучше вертикального

Миф: горизонтальное масштабирование всегда лучше вертикального

MAATRIX

На собеседовании, на конференции, в статье про архитектуру Netflix или Google — везде звучит одно и то же: «настоящие» системы масштабируются горизонтально, вертикальное масштабирование — это временная затычка для тех, кто ещё не дорос. Проблема в том, что этот тезис верен для компаний с нагрузкой, которую физически не выдержит ни один отдельный сервер, и почти всегда вреден для проекта, который просто хочет расти без лишней сложности. Разберём, откуда взялась эта мода, чем вертикальный рост реально проще горизонтального и как выбрать путь под свою нагрузку, а не под чужую презентацию.

Откуда взялся миф про превосходство горизонтального масштабирования

Тезис «scale out — это правильно, scale up — это костыль» пришёл из вполне конкретного места: доклады и блог-посты компаний, которые обслуживают десятки и сотни миллионов пользователей. У Google, Netflix, Amazon действительно нет выбора — их нагрузка физически не помещается ни в один сервер, каким бы мощным он ни был, и распределённая архитектура для них не роскошь, а единственный работающий вариант. Их инженеры пишут об этом честно и подробно, потому что это интересная и сложная инженерная задача.

Проблема в переносе контекста. Доклад про архитектуру, рассчитанную на нагрузку, которая у 99% читателей никогда не случится, воспринимается как универсальный рецепт «как правильно строить системы». Добавьте маркетинг облачных провайдеров, которым выгодно продавать много мелких инстансов вместо одного крупного, культуру «cloud-native» как знак инженерной зрелости — и получаете ситуацию, когда сайт-визитка или SaaS на первую сотню клиентов проектируется так, будто завтра придёт трафик уровня Чёрной пятницы Amazon. Та же механика переноса чужого опыта на свою задачу разобрана с другого угла в статье про миф о мгновенном и бесконечном масштабировании облака.

Отдельно стоит фактор резюме: опыт с Kubernetes и шардированием звучит весомее, чем «настроил PostgreSQL с репликацией и написал нормальный кэш». Это не злой умысел, но он тихо подталкивает решения в сторону избыточной сложности там, где задача этого не требует.

Чем вертикальное масштабирование объективно проще

Прежде чем спорить, что «лучше», стоит честно перечислить, что вертикальный рост даёт бесплатно, а горизонтальный — только ценой дополнительной работы.

Данные остаются в одном месте. Один сервер с базой данных не знает проблемы консистентности между узлами — транзакция либо прошла целиком, либо откатилась, и вам не нужно думать про eventual consistency, конфликты при одновременной записи на разных нодах или CAP-теорему в её практическом изводе. Горизонтальное масштабирование БД (шардирование, мульти-мастер репликация) — одна из самых сложных областей в инженерии, и обходить её стороной, пока реально можно обойтись, — это не лень, а трезвый расчёт.

Приложению не нужно быть stateless. Сессии пользователей, локальный кэш в памяти процесса, временные файлы на диске, WebSocket-соединения, привязанные к конкретному процессу — всё это работает «из коробки» на одном сервере. Как только серверов становится больше одного, любое из этих мест превращается в источник багов: пользователя раскидывает балансировщик на разные ноды, и сессия «теряется», потому что жила в памяти конкретного процесса. Чтобы это исправить, сессии выносят в Redis, файлы — в общее хранилище, WebSocket — за отдельный слой маршрутизации. Каждый такой вынос — новый компонент инфраструктуры, новая точка отказа и новая вещь, которую нужно администрировать.

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

Развёртывание и обслуживание — на порядок проще. Обновление кода, миграция базы данных, ротация сертификатов, установка патчей безопасности — на одном сервере это последовательность понятных шагов. В кластере приходится думать про rolling deployment и про то, что часть запросов в момент обновления обслуживается старой версией кода, а часть — новой, и обе версии должны быть совместимы со схемой БД одновременно. Это решаемо, но это отдельная дисциплина, которую нужно выстроить и поддерживать.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Когда один мощный сервер экономичнее и надёжнее

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

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

Для типичного проекта — интернет-магазина на несколько тысяч заказов в месяц, B2B SaaS на пару сотен компаний, корпоративного портала — современный мощный сервер с NVMe-дисками и достаточным запасом оперативной памяти закрывает нагрузку с большим запасом, и узким местом на практике почти всегда оказывается не CPU и не RAM, а неоптимизированные запросы к базе или отсутствие кэширования — вещи, которые докупкой второго сервера не решаются вообще. Иногда выгоднее не докупать ресурсы, а один раз найти и убрать узкое место в коде — этому выбору посвящён отдельный разбор про то, когда вертикальный рост дешевле переписывания кода.

Надёжность у одного сервера тоже не автоматически хуже — она просто устроена по-другому. Вместо распределённой отказоустойчивости вы полагаетесь на резервирование внутри сервера (RAID-массив, резервный блок питания, резервируемая сетевая карта у крупных провайдеров), регулярные бэкапы и заранее посчитанный план восстановления. Для многих задач ощутимый, но конечный простой на восстановление из бэкапа — приемлемый компромисс, если он честно посчитан заранее, а не выясняется в момент инцидента.

Когда горизонтальное масштабирование действительно оправдано

Ровно наоборот: есть ситуации, где вертикальный рост не спасает в принципе, и тянуть с переходом на распределённую архитектуру — тоже ошибка, просто в другую сторону.

Нагрузка реально превышает возможности одного сервера. Это происходит не тогда, когда сервер «загружен на 70%», а когда вы упёрлись в потолок конфигураций, которые вообще существуют на рынке, — либо по CPU/RAM, либо по пропускной способности сети или диска. До этого потолка на практике добираются немногие проекты, но если вы туда добрались — горизонтальное масштабирование не опция, а необходимость.

Нужна географическая распределённость. Если у вас пользователи в России, США и Великобритании одновременно и сетевая задержка до сервера ощутима для продукта (торговля, реалтайм-сервисы, игры), один сервер физически не может быть одинаково близко ко всем — расстояние и скорость света никакой мощностью не компенсировать. Здесь горизонтальное масштабирование решает не проблему мощности, а проблему географии — и это отдельная, законная причина.

Требуется отказоустойчивость на уровне SLA, а не «в среднем работает». Если контракт с заказчиком или регуляторные требования обязывают держать доступность на уровне, который не допускает простоя даже на время планового обслуживания или отказа одного узла, — вертикальное масштабирование эту задачу не решит в принципе, потому что у него всегда есть единственная точка отказа: сам сервер.

Нагрузка резко и непредсказуемо скачет во времени. Билетный сервис перед продажей, сервис под сезонную распродажу, инфраструктура под вирусный контент — здесь горизонтальное масштабирование (в том числе автоматическое) даёт возможность кратковременно нарастить мощность и потом её сократить, чего вертикальный апгрейд в большинстве случаев не позволяет сделать так же быстро и без простоя.

Важно: во всех этих случаях горизонтальное масштабирование оправдано не потому, что «так правильно», а потому что есть конкретное, измеримое ограничение, которое вертикальный путь не закрывает. Если такого ограничения нет — распределённая архитектура добавляет сложность без компенсирующей пользы, и это тот самый антипаттерн, который подробно разобран на примере кластера из трёх серверов под сайт-визитку.

Гибридный путь: как растёт большинство реальных проектов

На практике редкий проект выбирает горизонтальное или вертикальное масштабирование раз и навсегда — обычно это последовательность шагов, и она почти всегда идёт в одном порядке.

  1. Один сервер под всё — приложение, база данных, кэш, очередь задач на одной машине. Для старта это не временное решение «пока не доросли», а разумная архитектура сама по себе.
  2. Вертикальный апгрейд по мере роста нагрузки — больше vCPU и RAM, переход на NVMe. Занимает минуты и не требует изменений в коде.
  3. Разнесение ролей по серверам — БД переезжает на отдельную машину, кэш (Redis/Memcached) — на свою. Каждый компонент по-прежнему один, но это уже первый шаг к распределённой архитектуре: появляется сеть между компонентами и вопрос, что делать, если одна из машин недоступна.
  4. Реплики на чтение для базы данных — мастер принимает запись, реплики обслуживают чтение. Снимает нагрузку на чтение без шардирования и без потери консистентности записи.
  5. Горизонтальное масштабирование веб-слоя — несколько одинаковых серверов приложения за балансировщиком, при условии, что приложение уже stateless.
  6. Горизонтальное масштабирование базы данных — шардирование или мульти-мастер репликация. Самый сложный и самый редко реально нужный шаг: большинство проектов закрывают нагрузку на шаге 4–5 и никогда сюда не доходят.

Каждый следующий шаг откладывается до момента, когда предыдущий реально исчерпан, а не берётся «про запас». Компания, которая перепрыгивает сразу на шаг 5–6, потому что «так делают в больших проектах», платит сложностью шага 6 за нагрузку уровня шага 2.

Методика выбора: как решить именно для своей ситуации

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

1. Упирается ли текущая нагрузка в физический потолок одного сервера? Проверьте реальную утилизацию CPU, RAM, диска и сети под пиковой нагрузкой — не «кажется, что скоро понадобится», а фактические цифры из мониторинга. Если запас есть — вертикальный апгрейд закроет проблему быстрее и дешевле, чем перестройка архитектуры.

2. Узкое место — действительно мощность, или это код и запросы к базе? Медленные ответы под нагрузкой чаще всего вызваны N+1-запросами, отсутствием индексов, синхронными вызовами внешних API или отсутствием кэша — ни одна дополнительная машина эти проблемы не решает, она просто масштабирует их вместе с остальной системой.

3. Есть ли требование, которое вертикальный рост в принципе не закрывает? Географическая распределённость, SLA без единой точки отказа, нагрузка, превышающая любую доступную на рынке конфигурацию сервера, — если хотя бы одно из этого подтверждено реальным контрактом или измеренным трафиком, а не гипотезой «на всякий случай», это законный повод идти в горизонтальную архитектуру.

4. Кто будет обслуживать выбранную архитектуру дальше? Команда из одного-двух инженеров с распределённой системой из шести компонентов рискует тратить больше времени на поддержание инфраструктуры, чем на продукт. Честная оценка своих ресурсов — часть инженерного решения, а не признак слабости.

5. Что произойдёт, если оценка нагрузки окажется неверной? Вертикальный путь обратим и дёшев в ошибке — если недооценили рост, апгрейд занимает минуты. Горизонтальный путь, начатый преждевременно, обратим намного хуже: демонтировать архитектуру, которая не была нужна, дороже и болезненнее, чем построить её позже, когда потребность подтвердилась.

Если по итогам этих пяти вопросов явного ответа «нужна горизонталь» нет — начните с вертикального масштабирования. Оно не закрывает дверь к горизонтальному росту в будущем, оно просто откладывает связанную с ним сложность до момента, когда она реально окупится.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Если сейчас выбрать вертикальное масштабирование, не придётся ли потом переписывать всё заново под горизонтальное?

Частично да, но не полностью. Разделение ролей (БД отдельно от приложения, кэш отдельно от БД) стоит закладывать заранее — это дёшево и не мешает жить на одном сервере. А вот stateless-архитектуру приложения (вынос сессий, файлов) можно откладывать до момента, когда она реально понадобится, без штрафа за «опоздание».

Есть ли предел, до какого имеет смысл растить один сервер вертикально?

Практический предел — конфигурации, реально доступные у провайдеров: обычно это десятки ядер и сотни гигабайт оперативной памяти. До этого потолка вертикальный путь почти всегда выгоднее горизонтального по соотношению цена/сложность; выше него выбора уже не остаётся.

А как же отказоустойчивость — один сервер ведь единая точка отказа?

Да, и это честное ограничение. Компенсируется резервированием внутри сервера (RAID, резервное питание у провайдера), регулярными протестированными бэкапами и заранее посчитанным временем восстановления. Для многих задач непродолжительный простой при аварии — приемлемый компромисс против постоянной сложности кластера; для задач, где это неприемлемо, ответ уже дан в разделе про законные причины горизонтального роста.

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

Когда вы упёрлись в максимальную доступную конфигурацию сервера у выбранного провайдера, либо когда появилось конкретное измеримое требование (SLA, география, пиковая нагрузка вне зависимости от мощности одной машины), а не ощущение «наверное, скоро понадобится».

Дорого ли потом мигрировать с одного мощного сервера на несколько?

Дороже, чем расти горизонтально с самого начала, но обычно дешевле, чем несколько лет поддерживать распределённую архитектуру, которая не была нужна. Миграция делается поэтапно (сначала вынос БД, потом кэша, потом stateless веб-слоя) и не требует останавливать продукт на всё время перехода.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →