В позавчерашнем примере мы шардили базу по user_id и это кажется логичным и очевидным решением. Все данные одного юзера в одном месте, джойны не разъезжаются по базам — красота! Но это только на первый взгляд. В реальности такой подход приносит кучу проблем.
Представим соцсеть, где user_id используется как ключ шардирования. У одних пользователей тысячи постов и миллионы подписчиков, у других — пара репостов котиков. В итоге один шард разрывается от нагрузки, пока остальные скучают без дела. Получаем классический hot shard — и вся идея равномерного распределения летит в трубу.
А еще есть запросы вроде "показать популярные посты за неделю" или "найти общих друзей". Придется опрашивать все шарды, собирать результаты и сортировать на лету. Латенси растет, ресурсы тратятся впустую — а все из-за неудачного выбора ключа.
Как выбрать ключ с умом? Отталкиваемся от паттернов доступа к данным. Для ленты новостей отлично подойдет шардинг по дате создания поста — свежий контент всегда под рукой. В e-commerce хорошо работает географический шардинг — заказы обычно привязаны к региону доставки.
В играх с открытым миром шардируем по координатам игровых зон. В системах логирования — по временным интервалам. В микросервисной архитектуре часто шардируют по tenant_id, чтобы данные одного клиента были изолированы.
Универсальное правило — ключ должен обеспечивать равномерное распределение данных и минимизировать cross-shard запросы. Если 80% запросов укладываются в один шард — значит ключ выбран правильно.
И не бойтесь сложных схем! Составной ключ из
{region_id, created_at} или {category_id, product_id} часто работает лучше, чем один простой параметр. Главное — тщательно проанализировать характер нагрузки перед выбором стратегии шардирования.PS Ссылка на картинку в хорошем разрешении
🏴☠️ @happy_devops
