Базы данных
Sharding: спровоцировать и укротить hot shard
Читать про hot shard — не то же самое, что видеть, как один шард взбирается к 94% CPU, пока остальные простаивают, а затем перерезать виновного арендатора на собственный шард с sub-second паузой. Поднимите небольшой Citus-кластер, загоните его в каноническую неисправность sharding и применяйте плейбук юнита, пока перекос не сгладится — с доказательствами на каждом шаге.
Превратите ментальную модель юнита в воспроизводимый операционный цикл: спроектируйте ко-локированную схему, шардированную по tenant_id, загрузите степенное распределение арендаторов, обнаружьте hot shard по skew и пер-арендаторским метрикам, изолируйте выброс онлайн и проверьте исправление числами до/после.
Поднять Citus-кластер с несколькими worker'ами и ко-локированной схемой, шардированной по tenant_id, намеренно создать hot shard степенной нагрузкой арендаторов, затем обнаружить и изолировать арендатора-выброс онлайн — доказав улучшение перекоса и латентности измерениями, а не оценками.
- Таблица до/после: отношение перекоса размера шардов max/median, CPU горячего worker %, P99 whale и P99 мелкого арендатора — всё измерено под одинаковой нагрузкой, а не оценено.
- Вывод EXPLAIN (или планы запросов), доказывающий, что ко-локированный join — single-worker, а не ко-локированный join уходит в fan-out по всем worker'ам.
- Доказательство, что изоляция была онлайн: измеренная пауза записи sub-second, и кластер обслуживал трафик всё время (без maintenance window).
- Абзац-описание: почему isolate_tenant_to_new_shard устранил перекос там, где citus_rebalance_start() не устранил бы, и какие опережающие индикаторы (отношение skew, доля на арендатора) вы бы алертили, чтобы предупредить следующий инцидент.
- Добавьте многоуровневую политику изоляции как скрипт/cron: запрашивайте долю на арендатора из pg_stat_statements и авто-изолируйте любого арендатора, пересекающего ~5% времени запросов кластера; продемонстрируйте срабатывание на синтетическом паттерне роста до насыщения CPU.
- Отработайте online resharding: добавьте четвёртый worker и запустите citus_rebalance_start(); убейте координатор посреди переезда и покажите, что ребалансировщик возобновляется идемпотентно из pg_stat_subscription без потери данных.
- Спровоцируйте cross-shard транзакцию (обновите ко-локированную таблицу плюс таблицу с другим ключом в одном BEGIN/COMMIT), пронаблюдайте путь 2PC, затем уроните координатор посреди prepare и продемонстрируйте обнаружение и разрешение зависшей записи в pg_prepared_xacts через COMMIT/ROLLBACK PREPARED.
- Постройте схему вторым способом — schema-based sharding из Citus 12 (одна схема на арендатора) — и сравните эргономику онбординга/офбординга и накладные расходы планирования с row-based вариантом.
Это цикл, который вы будете прогонять в каждом реальном инциденте sharding: проектируйте под ко-локацию, чтобы частый случай оставался single-node, инструментируйте перекос шардов и пер-арендаторскую нагрузку как опережающие индикаторы, изолируйте арендатора-выброс онлайн, а не хватайтесь за ребалансировку, которая оставляет его в связке, и проверяйте числами до/после под одинаковой нагрузкой. Сделав это однажды на игрушечном Citus-кластере, вы доводите продакшен-версию — где whale-арендатор это платящий enterprise-аккаунт, а часы on-call тикают — до мышечной памяти.