Перейти к содержимому
Масштабирование БД

Масштабирование БД

Масштабирование баз данных: вертикальное (увеличение мощности одного сервера) и горизонтальное (добавление новых серверов). Репликация (копирование данных для масштабирования чтения и отказоустойчивости) и шардирование (разбиение данных для масштабирования записи). Компромиссы CAP-теоремы (согласованность vs доступность), стоимость масштабирования и типичные ошибки.

Введение: Когда один сервер перестаёт справляться

Представьте, что у вас есть небольшой магазин. За день заходит 50 человек — вы справляетесь. Через месяц — 500 человек. Вы нанимаете ещё одного продавца. Через год — 5000 человек в день. Ваш маленький магазин не вмещает всех. Что делать? Можно переехать в огромный торговый центр (вертикальное масштабирование). А можно открыть несколько магазинов в разных районах города (горизонтальное масштабирование).

С базами данных та же история. Сначала вы ставите PostgreSQL на один сервер. Данных немного, запросов мало. Потом бизнес растёт. Данных становится всё больше. Запросов — всё больше. Один сервер перестаёт справляться: медленные ответы, долгие бэкапы, высокий CPU.

Масштабирование базы данных — это способность системы увеличивать свою производительность и ёмкость при росте нагрузки. Существует два основных подхода: вертикальное масштабирование (увеличиваем мощность одного сервера) и горизонтальное масштабирование (добавляем новые серверы).

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

Два типа масштабирования

ТипЧто делаемАналогия
ВертикальноеУвеличиваем мощность одного сервераПереезжаем в больший офис
ГоризонтальноеДобавляем новые серверыОткрываем филиалы

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

Что это

Вы берёте существующий сервер и делаете его мощнее: больше CPU, больше RAM, быстрее диски. Или переезжаете на более крупный сервер в облаке.

Как это выглядит

Было:
  - 4 CPU, 16 GB RAM, SSD 500 GB

Стало:
  - 16 CPU, 64 GB RAM, SSD 2 TB

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

ПреимуществоОбъяснение
ПростотаНе нужно менять архитектуру приложения
СовместимостьВсе функции базы данных работают как раньше
ТранзакцииACID, внешние ключи, JOIN — всё сохраняется
УправлениеОдин сервер проще администрировать

Недостатки

НедостатокОбъяснение
Физический пределНельзя бесконечно увеличивать мощность
СтоимостьСамые мощные серверы очень дороги
Отсутствие отказоустойчивостиСервер упал — всё упало
Простой при апгрейдеЧтобы увеличить память, часто нужна остановка

Когда использовать

Подходит:
  - Начальный этап (пока нагрузки мало)
  - Данные помещаются на один сервер
  - Бюджет позволяет купить мощный сервер
  - Нет времени/ресурсов на сложную архитектуру

Не подходит:
  - Данные > 10 ТБ (дорого)
  - Запросов > 10 000 в секунду
  - Нужна отказоустойчивость

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

Что это

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

Как это выглядит

Было:
  - 1 сервер (4 CPU, 16 GB RAM)

Стало:
  - 5 серверов (каждый 4 CPU, 16 GB RAM)
  - Итого: 20 CPU, 80 GB RAM

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

ПреимуществоОбъяснение
Теоретически безлимитноМожно добавлять серверы бесконечно
ДешевлеМного маленьких серверов дешевле одного огромного
ОтказоустойчивостьЕсли один сервер упал, другие работают
ГибкостьМожно добавлять серверы по мере роста

Недостатки

НедостатокОбъяснение
СложностьПриложение должно знать о нескольких серверах
Ограниченные возможностиНе все базы данных хорошо шардируются
ТранзакцииРаспределённые транзакции сложны
JOINJOIN между разными серверами медленные или невозможны

Когда использовать

Подходит:
  - Данные > 1 ТБ
  - Запросов > 10 000 в секунду
  - Нужна отказоустойчивость
  - Бюджет ограничен (много маленьких серверов дешевле)

Не подходит:
  - Маленькие проекты (избыточно)
  - Требуются сложные транзакции
  - Команда не имеет опыта распределённых систем

Способы горизонтального масштабирования

1. Репликация (Replication)

Данные копируются на несколько серверов. Один сервер — мастер (пишем в него), остальные — реплики (читаем из них).

    graph LR
    A[Мастер] --> B[Реплика 1]
    A --> C[Реплика 2]
    A --> D[Реплика 3]
  

Преимущества: Отказоустойчивость, распределение чтения.

Недостатки: Запись идёт в один сервер (узкое место), задержка репликации.

Когда использовать: Чтения » записи, нужна отказоустойчивость.

2. Шардирование (Sharding)

Данные разбиваются на части (шарды) и распределяются по разным серверам. Каждый сервер хранит только часть данных.

Шард 1: пользователи с id 1-1000
Шард 2: пользователи с id 1001-2000
Шард 3: пользователи с id 2001-3000

Преимущества: Линейное масштабирование (добавили сервер — увеличили ёмкость).

Недостатки: Сложность, JOIN между шардами невозможны, перебалансировка при добавлении сервера.

Когда использовать: Данные не помещаются на один сервер, нагрузка на запись высокая.

3. Партиционирование (Partitioning)

Разбиение данных внутри одного сервера (физическое разделение). Не требует нескольких серверов.

Таблица orders:
  - Партиция 2024-01: заказы января
  - Партиция 2024-02: заказы февраля

Преимущества: Ускорение запросов (поиск только в нужной партиции), упрощение удаления старых данных.

Недостатки: Всё ещё один сервер.

Масштабирование чтения

Когда запросов на чтение больше, чем может обработать один сервер, помогает репликация.

Архитектура:
  - Мастер: пишем
  - 5 реплик: читаем
  - Приложение распределяет запросы между репликами

Результат:
  - В 5 раз больше запросов на чтение
  - Отказоустойчивость (реплика упала — есть другие)

Ограничения:

  • Запись всё равно идёт в мастер (может быть узким местом)
  • Задержка репликации (реплики могут быть не совсем свежими)

Масштабирование записи

Когда запросов на запись много, репликация не помогает (пишем всё равно в один мастер). Нужно шардирование.

Архитектура:
  - Шард 1: пользователи 0-999
  - Шард 2: пользователи 1000-1999
  - Шард 3: пользователи 2000-2999

Запись:
  - Пользователь с id=500 → шард 1
  - Пользователь с id=1500 → шард 2
  - Пользователь с id=2500 → шард 3

Выбор ключа шардирования (shard key):

Хороший ключПлохой ключ
Равномерно распределяет данныеСоздаёт “горячие” шарды
Стабильный (не меняется)Часто меняется
Используется в большинстве запросовРедко используется в запросах

Масштабирование в разных типах БД

Реляционные БД (PostgreSQL, MySQL)

ПодходПростотаЭффективность
ВертикальноеВысокаяСредняя
РепликацияСредняяВысокая (для чтения)
ШардированиеНизкаяВысокая (для записи)

Реальность: Реляционные БД создавались для вертикального масштабирования. Горизонтальное — возможно, но сложно. Требует ручного управления или специальных расширений (Citus для PostgreSQL, Vitess для MySQL).

Нереляционные БД (MongoDB, Cassandra)

ПодходПростотаЭффективность
ВертикальноеВысокаяСредняя
РепликацияВысокаяВысокая
ШардированиеВысокаяВысокая

Реальность: NoSQL БД создавались для горизонтального масштабирования. Шардирование и репликация встроены “из коробки”.

Примеры архитектур

Маленький проект (начало)

Один сервер PostgreSQL:
  - 4 CPU, 16 GB RAM
  - Данные: 10 GB
  - Запросов: 100 в секунду

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

Средний проект (рост)

PostgreSQL мастер + 2 реплики:
  - Мастер: запись
  - Реплики: чтение

Масштабирование: репликация

Большой проект (миллионы пользователей)

Шардированный PostgreSQL (Citus) + реплики:
  - Шард 1 + реплики
  - Шард 2 + реплики
  - Шард 3 + реплики

Масштабирование: шардирование + репликация

Очень большой проект (миллиарды записей)

Cassandra (NoSQL):
  - 100 узлов
  - Репликация: 3 копии
  - Шардирование: автоматическое

Масштабирование: горизонтальное (из коробки)

Компромиссы CAP-теоремы

При горизонтальном масштабировании приходится выбирать между:

ВыборЧто жертвуем
CP (Consistency + Partition tolerance)Доступность (при разделении сети система не отвечает)
AP (Availability + Partition tolerance)Согласованность (данные могут быть временно не свежими)

Что это значит для аналитика:

  • CP-системы (HBase, MongoDB по умолчанию) — строгая согласованность, но возможна недоступность при сетевых проблемах. Для финансов, бронирования.
  • AP-системы (Cassandra, DynamoDB) — высокая доступность, но eventual consistency. Для логов, социальных сетей.

Стоимость масштабирования

Вертикальное

Сервер 4 CPU, 16 GB: $100/мес
Сервер 16 CPU, 64 GB: $400/мес
Сервер 64 CPU, 256 GB: $2000/мес

Цена растёт нелинейно.

Горизонтальное

5 серверов по 4 CPU, 16 GB: 5 × $100 = $500/мес
10 серверов по 4 CPU, 16 GB: 10 × $100 = $1000/мес

Цена растёт линейно.

Вывод: Для больших объёмов горизонтальное масштабирование дешевле.

Распространённые ошибки

Ошибка 1: Позднее масштабирование

Ждут, пока сервер упадёт, и только тогда начинают думать о масштабировании.

Решение: Мониторить CPU, RAM, IOPS, размер данных. Планировать масштабирование заранее.

Ошибка 2: Шардирование преждевременно

Шардирование на 100 серверов, когда данных на 10 GB. Сложность не оправдана.

Решение: Начинать с вертикального. Переходить на горизонтальное только когда вертикальное упёрлось в потолок.

Ошибка 3: Неправильный ключ шардирования

Выбрали ключ, который создаёт “горячий” шард (например, статус “active”).

Решение: Выбирать ключ с равномерным распределением.

Ошибка 4: Игнорирование задержки репликации

Читают с реплики сразу после записи в мастер. Данные ещё не продублировались.

Решение: Читать с мастера для критичных данных, использовать read-after-write consistency.

Ошибка 5: JOIN между шардами

Пытаются сделать JOIN между таблицами, которые находятся на разных шардах.

Решение: Денормализация, изменение схемы, выбор другого ключа шардирования.

Резюме

  1. Два типа масштабирования: вертикальное (мощнее сервер) и горизонтальное (больше серверов).

  2. Вертикальное: просто, но есть потолок, дорого на больших объёмах. Для начала проекта, для малых и средних нагрузок.

  3. Горизонтальное: сложно, но безлимитно, дешевле на больших объёмах. Для больших данных, высокой нагрузки, отказоустойчивости.

  4. Репликация — копирование данных. Для масштабирования чтения и отказоустойчивости.

  5. Шардирование — разбиение данных. Для масштабирования записи.

  6. CAP-теорема — при горизонтальном масштабировании выбираем между согласованностью и доступностью.

  7. Стоимость: горизонтальное дешевле для больших объёмов.