TGViewer
Павел Сорокин | Java Павел Сорокин | Java @s0r0kln · 9.16K subscribers
Post #459 3.65K
Шардирование: когда одна база уже не вывозит

Однажды база данных становится слишком большой. Запросы тормозят, индексы пухнут, реплики для чтения уже не спасают. Да, можно вертикально отмасштабировать - накинуть сервак помощнее, памяти побольше, но в какой-то момент уже не получится растить мощности бесконечно

И тут появляется шардирование - разделение данных на несколько независимых частей, которые называются шардами

То есть мы не просто оптимизируем одну большую таблицу, а распределяем данные между несколькими базами или узлами

Например, пользователи с одними user_id живут в одном шарде, с другими user_id - в другом


shardKey = user_id % 4

0 → shard_0
1 → shard_1
2 → shard_2
3 → shard_3


То есть по user_id мы сразу понимаем, в какой шард идти. В теории круто: было много данных в одной базе, стало меньше данных в каждой отдельной базе

НО не все так просто, потому что мы получили несколько доп. сложностей. Очевидно стала более сложная инфра: была одна БДшка - стало 4. Нужны новые серваки, мониторинг за каждой, поддержка и тд

Но с точки зрения работы с данными - главная боль шардирования в том, что теперь данные распределены

Раньше можно было сделать обычный запрос:


SELECT * FROM orders WHERE user_id = 123;


И база сама разбиралась, где что лежит. После шардирования приложение или специальный routing layer должны сначала понять, в каком шарде лежит user_id = 123

Но и тут проблемы начинаются, когда мы заходим сделать запрос не по shard key


SELECT * FROM orders WHERE status = 'FAILED';


Если status не является ключом шардирования, то мы не знаем, в каком шарде лежат такие заказы

Значит, надо идти во все шарды, выполнить запрос в каждом, собрать результаты, склеить их и отдать клиенту. А если у нас 10 шардов, то это +10 сетевых вызовов и большой риск, что какой-то из этих запросов отвалится

Иногда это ОК, но если таких запросов много, то лучше пересмотреть архитектуру хранения данных

Еще больно становится с JOIN’ами

Классическая ситуация - надо достать user и все его связанные orders. В рамках одной БД это просто. Но если user и его orders лежат на разных шардах, то простым JOIN уже не получится. То есть ключом шардированя у order был бы не order_id, а user_id

❗️Поэтому один из самых важных вопросов при шардировании - по какому ключу шардировать

Плохой shard key может убить всю производительность

Во-первых плохой выбор может привести к распределенному запросу по шардам, что мы уже разобрали, и это not good

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

Это называется hot shard - когда нагрузка распределяется неравномерно, и один узел становится бутылочным горлышком

В реальности, конечно, это всегда компромисс, потому что всегда будет какой-то перекос. Главное предотвратить заранее проблему на этапе проектирования, а то потом будет дорого перераспределять кучу данных

Окей, а где это шардирование включить?

Такой вопрос может возникнуть, особенно у начинающих

В PostgreSQL шардирование не появляется магически из коробки. SQL БДшки вообще по дефолту не продоставляют такую функциональность. Если мы хотим шардировать SQL БД, то у нас есть два варианта:

🟣Писать свой routing layer в приложении

То есть мы обращаемся из кода также в обычный репозиторий userRepo.save(user), но под капотом он считает ключ шардирования и идет сам в нужный шард. Но эту логику надо писать самим. На моих проектах часто это была своя платформенная библиотека


int shardId = userId % shardCount;
DataSource dataSource = shardRouter.getDataSource(shardId);


🟣Есть расширения вроде Citus, которые можно накатывать на Postgres

За счет него БДшка «сама» будет роутить данные, мы просто обращаемся к узлу-координатору, а он дальше распределяет данные. Но это не бесплатно и в этом надо разобраться, а не просто включить галочкой. В общем, свои трудности

Ставь 🔥 , если заходят такие посты

P.S зацени, схему к посту)

#хардовая_польза
  • 🔥 125
  • 👍 7
  • ❤ 1
More from @s0r0kln
  1. Oct 9, 2026Еще пару часов рабочей недели и можно выдохнуть, а пока, уже по традиции: кидай в комменты…
  2. Oct 8, 2026Мы уже разбирали паттерны микросервисов, это часть 2 Есть ещё 5 ребят, без которых распред…
  3. Sep 21, 2026Нужна ваша помощь 😐 В общем, я сейчас планирую 2 эфира сделать в сентябре - навалить поле…
  4. Sep 21, 2026Я очень много работаю с нейронками. Но есть вещи, которые я им не доверяю Код написать, ош…
  5. Sep 17, 2026Иллюзия понимания. Мне нередко в комментах на ютубе пишут что-то в духе "Паша, ну ты ваще…
  6. Sep 16, 2026Памятка по подготовке к собесу
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →