← Назад к вопросам

В чем разница между вертикальным и горизонтальным масштабированиями?

2.0 Middle🔥 91 комментариев
#REST API и микросервисы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между вертикальным и горизонтальным масштабированием

Масштабирование — это способность системы обрабатывать растущую нагрузку. Существуют два основных подхода, каждый со своими преимуществами и недостатками.

Вертикальное масштабирование (Vertical Scaling)

Определение: Увеличение мощности отдельного сервера — добавление больше CPU, RAM, дискового пространства.

До:                     После вертикального:
┌──────────────┐       ┌──────────────────────┐
│  Сервер      │       │  Сервер (усиленный)  │
│  4 CPU       │  →    │  16 CPU              │
│  8 GB RAM    │       │  64 GB RAM           │
│  100 GB SSD  │       │  1 TB SSD            │
└──────────────┘       └──────────────────────┘

Примеры:

// Вертикальное масштабирование
// До: t2.small (1 vCPU, 2 GB RAM) на AWS
// После: t3.2xlarge (8 vCPU, 32 GB RAM) на AWS

Преимущества:

  1. Просто реализовать — просто обновите сервер
  2. Нет изменений в коде приложения
  3. Нет сложности с распределённостью
  4. Проще с состоянием (state) — всё на одном сервере
  5. Единая БД, нет проблем консистентности
// Приложение остаётся как есть:
public class SimpleApp {
    public static void main(String[] args) {
        Server server = new Server(8080);
        server.start();  // Обработает больше запросов благодаря мощнее CPU/RAM
    }
}

Недостатки:

  1. Физический лимит — нет сервера с бесконечной мощностью
  2. Дорого — очень мощные серверы стоят экспоненциально дороже
  3. Downtime — нужно остановить сервер для обновления
  4. Single point of failure — один сервер = один отказ
  5. Нет распределения нагрузки — всё идёт на один узел
Вертикальное масштабирование имеет потолок:

┌─────────────┐
│ Мощность    │  ←← Здесь лимит
│ сервера     │  (самый мощный железо)
└─────────────┘
      ▲
      │ Стоимость растёт экспоненциально!
      │ (2x мощности ≠ 2x стоимость)

Горизонтальное масштабирование (Horizontal Scaling)

Определение: Увеличение количества серверов в системе, распределяя нагрузку между ними.

До:                     После горизонтального:
┌──────────────┐
│  Сервер      │       ┌──────────────┐
│  4 CPU       │       │  Сервер 1    │
│  8 GB RAM    │   →   │  4 CPU, 8GB  │
└──────────────┘       └──────────────┘
                       ┌──────────────┐
                       │  Сервер 2    │
                       │  4 CPU, 8GB  │
                       └──────────────┘
                       ┌──────────────┐
                       │  Сервер 3    │
                       │  4 CPU, 8GB  │
                       └──────────────┘
                       ┌────────────────────┐
                       │  Load Balancer     │
                       └────────────────────┘

Архитектура с горизонтальным масштабированием:

// Load Balancer (Nginx, HAProxy, облачные сервисы)
public class LoadBalancer {
    private List<Server> servers = Arrays.asList(
        new Server("server1:8080"),
        new Server("server2:8080"),
        new Server("server3:8080")
    );
    
    public void handleRequest(Request req) {
        // Round-robin, least connections, IP hash и т.д.
        Server selected = selectServer();  // Выбираем сервер
        selected.handle(req);  // Отправляем запрос
    }
}

Преимущества:

  1. Нет физического лимита — можно добавлять серверы бесконечно
  2. Дешевле — много дешёвых серверов дешевле одного супер-мощного
  3. Без downtime — добавляем новый сервер, не трогая старые
  4. Отказоустойчивость — если один сервер упадёт, другие работают
  5. Гибкость — быстро реагируем на спайки нагрузки (автоскейлинг)
Горизонтальное масштабирование масштабируется линейно:

┌──────────────────────────────┐
│ Мощность системы             │
│              ▲               │ ← Растёт линейно
│              │  ╱╱           │   (N серверов = N × мощность)
│              │ ╱╱            │
│              │╱╱             │
└──────────────────────────────┘
   Количество серверов →

Недостатки:

  1. Сложность — нужна согласованность данных между серверами
  2. Stateless приложение — сложнее работать с состоянием
  3. Сеть — больше сетевых вызовов, latency растёт
  4. Синхронизация БД — сложная проблема с репликацией/шардингом
  5. Operationalная сложность — нужен Load Balancer, мониторинг, автоскейлинг

Практический пример: Java приложение

Вертикальное масштабирование:

// Просто запускаем на более мощном сервере
public class Application {
    public static void main(String[] args) {
        // Было: На сервере t2.small (1 vCPU, 2 GB)
        // Теперь: На сервере t3.2xlarge (8 vCPU, 32 GB)
        // Код не меняется!
        
        ExecutorService executor = Executors.newFixedThreadPool(
            Runtime.getRuntime().availableProcessors()  // Автоматически 8 потоков
        );
        
        Server server = new Server(8080);
        server.start();
    }
}

Горизонтальное масштабирование:

// Нужны изменения в коде
public class DistributedApplication {
    public static void main(String[] args) {
        // Три инстанса приложения, слой load balancer
        
        // 1. Stateless контроллеры (обработка запросов)
        @RestController
        public class UserController {
            @GetMapping("/users/{id}")
            public User getUser(@PathVariable Long id) {
                // Каждый сервер может обработать любой запрос
                return userService.findById(id);
            }
        }
        
        // 2. Сессии хранятся в Redis, не в памяти сервера
        // (иначе клиент может попасть на другой сервер и потеряет сессию)
        @Bean
        public LettuceConnectionFactory connectionFactory() {
            return new LettuceConnectionFactory();
        }
        
        // 3. Кеши должны быть распределёнными
        @Bean
        public CacheManager cacheManager(LettuceConnectionFactory factory) {
            return RedisCacheManager.create(factory);
        }
    }
}

Сравнительная таблица

ПараметрВертикальноеГоризонтальное
РеализацияПростоСложно
СтоимостьВысокая при ростеЛинейная
DowntimeТребуетсяНет
ОтказоустойчивостьНизкаяВысокая
ЛимитыЕстьНет
Изменения в кодеМинимумМного
LatencyНизкийМожет быть выше
Консистентность данныхПростаяСложная
АвтоскейлингНетДа

Рекомендации

Используйте вертикальное, если:

  • Нагрузка предсказуема и не очень высока
  • Приложение имеет состояние (stateful)
  • Команда небольшая, нет опыта с распределёнными системами
  • Простота важнее масштабируемости

Используйте горизонтальное, если:

  • Нагрузка высокая и непредсказуема
  • Нужна отказоустойчивость
  • Приложение может быть stateless
  • Важна надёжность и отказоустойчивость

На практике: Современные системы обычно комбинируют оба подхода:

  • Горизонтальное масштабирование приложений
  • Вертикальное масштабирование БД (с кластерами для отказоустойчивости)
  • Кеширование (Redis) для снижения нагрузки на БД