Шардинг и репликация баз данных
(Раздел: Технологии и Инфраструктура)
Краткое резюме
Для iGaming-платформ рост трафика (ставки, депозиты, вебхуки PSP, события игр) и требования к доступности (≈99.9–99.99%) быстро упирают в предел одной БД. Репликация дает горизонтальное масштабирование чтения и отказоустойчивость; шардинг — горизонтальное масштабирование записи и данных. Ключ — осознанные компромиссы PACELC (после отказа: CA/P, иначе: Latency vs Consistency), четкие SLO и дисциплина схем/ключей.
Термины и модели
Репликация — копирование данных между узлами.
Leader–Follower (Primary–Replica): одна запись → много чтений.
Multi-Leader (Active–Active): записи в нескольких регионах, конфликты/мердж.
Consensus-replication (Raft/Paxos, NewSQL): кворумные записи (Cassandra/Scylla — AP-кворумы, CockroachDB/Yugabyte — CP-кворумы).
Sync / Semi-sync / Async: баланс задержки vs RPO.
Шардинг — горизонтальное разбиение таблиц/ключей по шардам.
Hash-шардинг (равномерность, сложнее диапазоны).
Range-шардинг (диапазоны ключей, риск «горячих» концов).
Consistent hashing (мягкое добавление/убавление нод).
Geo-шардинг (по региону/юрисдикции).
Функциональный шардинг (по доменам: платежи/ставки/CRM).
Когда и что выбирать в iGaming
Только репликация (без шардинга) — когда основная проблема в чтении: ленты событий, отчеты, публичные каталоги. Записи помещаются в один лидер, чтения — с реплик.
Шардинг — когда узкое место записи/хранения: поток ставок, транзакции балансов, триггерные события.
- Латентность к игрокам/PSP → локальные чтения с реплик.
- Регуляторика (локализация данных) → geo-шардинг.
- Межрегиональный DR → асинхронная реплика + план переключения.
PACELC и гарантийные свойства
CAP: при сети-сплите выбираем C (консистентность) или A (доступность).
PACELC: при отсутствии сбоев выбираем между Latency (L) и Consistency (C).
Денежные пути (баланс, списания): обычно C-ориентированные (CP/strict serializable или Serializable + бизнес-идемпотентность).
Менее критичные подсистемы (лог кликов, каталоги): L-ориентированные (AP/EC, eventual).
Репликация: практики
Leader–Follower
Записи → лидер, чтения → реплики (read scaling).
Read-after-write: для пользовательских операций читайте с лидера или ждите лаг (проверка `last_committed_lsn`/`wait_for_replay_lag`).
Semi-sync на критичных путях (снижение RPO ценой латентности).
Failover: автоматический (patroni/raft-координатор) + fencing (чтобы не было двойного лидера).
Multi-Leader
Годится для разделенных доменов и низкого конфликта (напр., контент/настройки), но не для единого счета игрока без специальных мер.
Политики мерджа: last-write-wins, CRDT, доменные правила консолидации.
Consensus / Кворумные БД
Запись с кворумом (например, `WRITE QUORUM`), чтение с кворумом (`READ QUORUM`) → сильная/настраиваемая консистентность.
Учитывайте латентность меж-AZ/регионов и стоимость кворума.
Шардинг: стратегии и выбор ключа
Как выбрать ключ
Стабильное распределение по player_id / account_id / bet_id.
Избегайте монотонных ключей (auto-increment) в range-шардинге — «горячий» хвост.
Для платежей — часто `player_id` или `account_id`; для логов — `event_time` + bucketing; для контента — `tenant_id`.
Стратегии
Hash-шардинг по player_id: баланс на потоке ставок/балансов.
Range-шардинг по времени для аналитики/архивов.
Geo-шардинг: EU-игроки → EU-шард (соответствие локальным законам).
Гибрид: hash внутри региона + geo по юрисдикции.
Борьба с «горячими» ключами
Key-salting (добавлять соль/bucket к ключу).
Write-throttling по сущности, очереди комманд (serial executor).
Материализовать «агрегаты» (баланс) в отдельном сторе с очередью последовательности.
Кросс-шардовые операции
Денежные перевод/компенсации: избегать 2PC на горячих путях.
Сага-паттерн: разбить на локальные транзакции + компенсирующие действия, жесткая идемпотентность и outbox.
2PC/протоколы коммита: допустимы точечно (бэк-офисные батчи), но дорогие по латентности и отказоустойчивости.
Проекции: читательские представления (read models) для междоменных экранов, обновляемые из стрима.
Схемы, индексы и эволюция
Версионирование схемы: миграции с back-compat, feature-flags на коде.
Индексы по ключам шардирования и частым запросам; избегать cross-shard join (делайте pre-join/денормализацию).
Для JSON/док-хранилищ — валидируйте схемы (JSON-Schema/Protobuf) и TTL для «шумных» коллекций.
Онлайн-масштабирование и ресхардинг
Планируйте N≫текущее количество виртуальных шардов (slots) → гибкий ребаланс.
Consistent hashing или «виртуальные ноды» для мягкого добавления узлов.
- двойная запись (старый+новый шард), валидация консистентности;
- фоновые копии чанков (logical dump / table move / streaming clone);
- переключение по «маркеру» + окно наблюдения, затем снятие двойной записи.
- Переезд лидера без простоя: переключение ролей, дренирование коннекшенов.
SLO, наблюдаемость и алертинг
SLO записи/чтения: p99 ≤ X мс на горячих таблицах, допустимый lag реплик ≤ Y секунд, доступность ≥ Z.
Метрики: TPS, p95/p99, replication lag, конфликтность (multi-leader), retry rate, deadlocks, lock wait, cache hit ratio, IOPS/latency диска.
Трассировка: `trace_id` в запросах БД, связывать с брокером/шиной событий.
Канареечные запросы и synthetic transactions для раннего детекта деградаций.
Безопасность и соответствие требованиям
Шифрование в покое и в транзите (TLS), ротация ключей.
RBAC/ACL, сегментация по доменам/тенантам, отдельные кластера для платежей/KYC.
Локализация данных (EU/TR/LATAM) — сочетайте geo-шардинг и политки ретенции.
Аудит: кто и что читал/правил; маскирование PII; экспорт аудита.
Бэкапы, PITR, DR
Полные + инкрементальные бэкапы, оффсайт-хранилище.
PITR (point-in-time recovery) для лидер-кластеров.
- Критичные домены (баланс/платеж) — RPO≈0–30с (semi-sync или частый WAL-шиппинг), RTO ≤ минуты с автоматическим failover.
- Менее критичные — RPO до минут/часов.
- DR-учения (game day) и документированный runbook переключения.
Производительность и тюнинг (кратко)
Память/кэш: увеличивайте буферы (shared buffers/innodb buffer pool), следите за cache-hit ≥ 95%.
Журнал/движок: быстрые NVMe, отдельный том под WAL/redo.
Пул соединений (PgBouncer/Hikari).
Планировщик/статистика: автованализа/автовакуум (Postgres), компакция/тюнинг GC (LSM-движки).
Кворумы/реплика-фактор: баланс между p99 и отказоустойчивостью.
Типовые топологии для iGaming
1) Балансы и платежи (CP-контур)
Leader–Follower в регионе игрока, semi-sync к близкой реплике.
Hash-шардинг по `account_id`.
Чтения «после записи» — с лидера; проекции в Redis для API-latency.
Outbox → шина событий для расчетов/аналитики.
2) История ставок/игровые события (AP-ориентированный лог)
Range-шардинг по времени или hash по `player_id` в колоночном/LSM-хранилище.
Асинхронные реплики для отчетности/OLAP.
Eventual consistency приемлема, важнее пропускная способность.
3) Профили/CRM (Multi-region read, локализация)
Geo-шардинг по юрисдикции, локальные реплики для чтений.
Записи через ближайший лидер; кросс-регион — асинхронно + разрешение конфликтов только для некритичных полей.
Примеры (концептуальные)
Postgres: декларативный шардинг по `player_id`
sql
CREATE TABLE player_wallet (
player_id BIGINT NOT NULL,
balance_cents BIGINT NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (player_id)
) PARTITION BY HASH (player_id);
CREATE TABLE player_wallet_p0 PARTITION OF player_wallet FOR VALUES WITH (MODULUS 32, REMAINDER 0);
--... p1..p31
-- Репликация: публикация WAL на реплики, синхронность для «горячего» региона.
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 (replica_eu1, replica_eu2)';
Кворумная запись (псевдо)
WRITE CL=QUORUM -- запись подтверждена большинством реплик
READ CL=LOCAL_QUORUM -- локальный кворум для низкой задержки
Сага вместо 2PC (упрощенно)
1. Списать депонирование на шард-A (idempotent).
2. Отправить событие «снято» → сервис выплат (шард-B).
3. Если шаг 2 неуспешен — компенсировать шаг 1 событием «возврат».
Чек-лист внедрения
1. Определите домены данных и SLO (p99, RPO/RTO, лаг реплик).
2. Выберите модель репликации (leader/follower, кворум) и стратегию шардинга.
3. Зафиксируйте ключи шардинга и схему (неизменяемые!).
4. Введите read-after-write политику и маршрутизацию чтений.
5. Спроектируйте online-ресхардинг (виртуальные шарды, двойная запись).
6. Гарантируйте идемпотентность и outbox для событий/команд.
7. Настройте бэкапы, PITR, DR и регулярные учения.
8. Включите наблюдаемость: лаг, кворумы, горячие ключи, конфликты.
9. Документируйте runbook: failover, split-brain, деградации.
10. Проведите нагрузочные/хаос-тесты под матчевые пики.
Антипаттерны
Один гигантский шард «на все» и «потом разрежем».
Кросс-шардовые join’ы на горячем пути запроса.
Отсутствие политики read-after-write (плавающие баги).
Миграции схем «ломающие» ключи шардинга.
Multi-leader для денежных счетов без строгой резолюции конфликтов.
Нет PITR/DR — невозможно восстановиться после логической ошибки.
Итоги
Репликация решает чтения и отказоустойчивость, шардинг — записи и объем. Успешная архитектура в iGaming — это четкие SLO и PACELC-компромиссы, стабильные ключи шардинга, минимум кросс-шардовой координации (сага вместо 2PC), дисциплина read-after-write, отлаженный online-ресхардинг и регулярные DR-учения. Такой подход масштабируется под пики турниров, выдерживает регуляторные ограничения по локализации данных и остается предсказуемым в эксплуатации.