Как масштабировать чтение в базе данных
Что проверяют
Понимаете ли вы, что масштабирование чтения делается ступенями и у каждой своя цена. Интервьюер ждёт, что вы начнёте с дешёвого (запросы, индексы, кэш) и дойдёте до реплик, не прыгая сразу к шардированию. Следом почти всегда спрашивают про задержку репликации: пользователь сохранил данные и не видит их.
Как отвечать
- сначала сам запрос:
EXPLAIN ANALYZE, недостающие индексы, N+1 в Hibernate (лечитсяJOIN FETCH,@EntityGraphили@BatchSize), выборка только нужных колонок через проекции; - пул соединений: HikariCP в Spring Boot идёт по умолчанию с
maximumPoolSize10, и раздувать пул бессмысленно, база раньше упрётся в CPU и блокировки. Когда инстансов приложения много, перед PostgreSQL ставят PgBouncer; - кэш: локальный Caffeine для горячих справочников, Redis для общего кэша между инстансами, в Spring это
@Cacheable. Заранее решите, как кэш инвалидируется: TTL, сброс при записи через@CacheEvictили по событию; - реплики чтения: запись идёт в primary, чтение на реплики. В Spring это
AbstractRoutingDataSource, который выбирает источник поTransactionSynchronizationManager.isCurrentTransactionReadOnly(), а читающие методы помечены@Transactional(readOnly = true). Обернуть его нужно вLazyConnectionDataSourceProxy, иначе соединение берётся раньше, чем транзакция узнает о флаге; - отдельная модель для чтения: материализованные представления, денормализованные таблицы или поисковый индекс в Elasticsearch или OpenSearch для сложных фильтров.
Шардирование упомяните последним: оно решает объём данных и нагрузку на запись, а для чтения обычно хватает реплик и кэша.
Где спотыкаются
Игнорируют лаг реплики. Пользователь сохранил профиль, следующий запрос ушёл на реплику, а там старые данные. Решение: читать свежие изменения пользователя с primary (read-your-writes) или направлять туда запросы в течение короткого окна после записи.
Добавляют кэш без плана инвалидации и потом ловят устаревшие цены и остатки.
Предлагают шардирование или Kafka там, где хватило бы индекса. Интервьюер прочитает это как непонимание порядка затрат.