Как масштабировать чтение базы данных под высокой нагрузкой?
- Что делать, если база не справляется с чтением?
- Зачем нужны реплики для чтения?
По порядку от дешёвого к дорогому: оптимизировать запросы и индексы → кэш → реплики для чтения → денормализация и модели чтения → шардирование.
- Сначала 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 без репликации
Что спросят дальше
- Чем грозит лаг репликации?
- Как выбрать ключ шардирования?
Разбор темы
- Масштабирование
Что именно упирается, вертикальный и горизонтальный рост, stateless и балансировка, шардинг и consistent hashing, реплики на чтение и лаг, автоскейл и поиск настоящего узкого места.
Связанные вопросы
- Пользователь сохранил изменения, обновил страницу — а изменений нет. Что происходит и как это исправить? Middle
- Как выбрать ключ и стратегию шардирования? Middle
- Как оценить, насколько кэш разгружает базу, и что будет, если он упадёт? Middle
- Зачем нужен пул соединений к базе и как выбрать его размер? Middle
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.