Вопрос с собеседования · System design

Как масштабировать чтение базы данных под высокой нагрузкой?

MiddleМасштабирование
Ещё спрашивают так:
  • Что делать, если база не справляется с чтением?
  • Зачем нужны реплики для чтения?
Коротко

По порядку от дешёвого к дорогому: оптимизировать запросы и индексы → кэш → реплики для чтения → денормализация и модели чтения → шардирование.

  • Сначала EXPLAIN: часто проблема в отсутствующем индексе или N+1, а не в мощности
  • Реплики масштабируют чтение, но отстают — свои изменения читать с лидера
  • Отдельное хранилище под тяжёлые запросы: поиск — в Elasticsearch, отчёты — в ClickHouse

А ещё Пул соединений и PgBouncer — чтобы база не тратила ресурсы на тысячи соединений

Подробно

1. Запросы. Медленные запросы ищут по pg_stat_statements и логу медленных запросов, разбирают EXPLAIN ANALYZE: недостающие индексы, лишние колонки, N+1 из ORM, OFFSET-пагинация. Это дешевле всего и часто даёт кратный эффект.

2. Кэш. Горячие и редко меняющиеся данные — в Redis или локальный кэш. Снимает основную долю чтения, если данные распределены неравномерно.

3. Реплики для чтения. Асинхронные реплики получают поток изменений и обслуживают SELECT. Ограничения: отставание (пользователь не видит только что сделанное — читать свои данные с лидера), запись по-прежнему в один узел, тяжёлые запросы на реплике могут тормозить применение журнала.

4. Модели под чтение. Денормализованные таблицы, материализованные представления, отдельные хранилища: полнотекстовый поиск — в Elasticsearch, аналитика — в ClickHouse через CDC, счётчики — предагрегированные.

5. Шардирование — когда не хватает одной машины по объёму или записи. Самое дорогое: межшардовые запросы, транзакции, решардинг.

Сопутствующее: пул соединений и PgBouncer, вертикальный рост машины (часто самый дешёвый способ выиграть время), архивирование холодных данных и партиционирование больших таблиц.

Что хотят услышать

  • Последовательность от дешёвых мер к дорогим.
  • Диагностика запросов до масштабирования.
  • Реплики и их отставание, кэш.
  • Отдельные хранилища под чтение и шардирование как последний шаг.

Частые ошибки

  • Сразу предлагать шардирование.
  • Добавлять реплики, не думая об отставании и чтении своих изменений.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Перенести все чтения в очередь сообщений и обрабатывать их пачками
  • ✓Реплики для чтения и кэш; помнить о лаге репликации и критичные чтения слать на лидер
  • ✗Увеличить число соединений в пуле приложения и отключить транзакции, чтобы чтения шли параллельно
  • ✗Заменить РСУБД на in-memory без репликации

Что спросят дальше

  • Чем грозит лаг репликации?
  • Как выбрать ключ шардирования?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования