В чем разница между шардированием и разбиением таблиц внутри одного инстанса?
Что проверяют
Различаете ли вы деление данных внутри одной базы и деление между разными серверами и понимаете ли, что второе переносит сложность в код приложения. Следом обычно просят рассказать, как в Go-сервисе выбрать шард по ключу и что делать с запросами, которым нужны данные из нескольких шардов.
Как отвечать
Главное различие в том, где лежат куски и кто их собирает.
- партиционирование: одна логическая таблица делится на секции внутри одного сервера. В PostgreSQL это декларативное партиционирование по диапазону, списку или хэшу (
PARTITION BY RANGE (created_at)). Приложение видит одну таблицу, а база сама отбрасывает лишние секции при запросе (partition pruning). Выигрыш в обслуживании: старые данные уходят черезDETACHилиDROPсекции вместо долгогоDELETE, индексы меньше,VACUUMидёт по частям. Если упёрлись в CPU, диск или память сервера, партиционирование не спасёт; - шардирование: данные разнесены по независимым инстансам, у каждого свои ресурсы. Это горизонтальное масштабирование и записи, и хранения. Цена: транзакции и
JOINмежду шардами, глобальные уникальные ID, решардинг при добавлении узлов.
В Go маршрутизацию часто пишут сами: держат по пулу *pgxpool.Pool на шард и выбирают нужный по хэшу ключа, например user_id. Чтобы добавлять узлы без полной перетасовки, используют консистентное хэширование или таблицу виртуальных бакетов. Альтернатива самописной логике: Vitess для MySQL (он сам написан на Go) или Citus для PostgreSQL.
Сильный финал: сначала пробуют партиционирование, реплики для чтения и более мощный сервер, а к шардированию приходят, когда один узел уже не вытягивает запись.
Где спотыкаются
Называют партиционирование вертикальным масштабированием. Вертикальное масштабирование это более мощный сервер, деление таблицы на секции к нему отношения не имеет.
Выбирают ключ шардирования без учёта запросов. Если шардировать заказы по order_id, а читать по пользователю, каждый запрос пойдёт на все шарды сразу.
Забывают про решардинг. Схема hash(key) % N при смене N перетасовывает почти все ключи, поэтому бакеты или консистентное хэширование закладывают заранее.