YDB (Yandex Database) — distributed SQL concept page. Multi-model: tables + KV + Kafka-like topics. Tablets как Bigtable (data shards с leader+followers через Paxos-like), Hive scheduler управляет placement и auto-split, DTX coordinator делает cross-tablet транзакции через deterministic ordering (не классический 2PC, не TrueTime). Distributed Storage layer — proprietary BlobStorage с erasure coding (1.5x overhead vs 3x replication) распределён по 3 DC. Три сценария: cross-tablet ACID транзакция через DTX, auto-split tablet на hot key (orders), geo-replication при падении DC2. Два ADR: YDB vs Spanner vs CockroachDB (когда что выбрать), и почему YDB использует свой DTX-протокол вместо классического 2PC.
YDB — opensource (Apache 2.0 с 2022) distributed SQL из Yandex. По классу — рядом со Spanner и CockroachDB: ACID-транзакции, serializable, горизонтальное масштабирование, multi-DC. Отличия: multi-model API (tables + KV + Kafka-compatible topics + document в одной системе), proprietary Distributed Storage на raw disks с erasure coding (~1.5x overhead вместо 3x при чистой репликации), собственный distributed transaction protocol вместо классического 2PC или TrueTime.
Берут, когда: сидите в Yandex Cloud и нужна managed база; российский enterprise с data residency / 152-ФЗ; multi-tenant SaaS, где удобно иметь tables и stream-топики в одном кластере без отдельного Kafka; интересен opensource NewSQL без BSL-лицензии CockroachDB.
«YDB = Spanner-like SQL/KV layer поверх tablets (шарды ~64MB-1GB), которые живут на raw-disk BlobStorage с erasure coding через 3 DC. Cross-tablet транзакция — deterministic log entry от координатора, оба tablet применяют в одном порядке (не prepare-vote round, не commit-wait по TrueTime).»
Три слоя в одном кластере:
cluster — корневая группа, multi-DC YDB деплоймент.
Внутри три подгруппы:
query-1, query-2) — stateless SQL/gRPC frontends. На query-1 повешены два ADR (см. ниже).tablet-a (range 0-1000), tablet-b (range 1001-2000), tablet-hot (orders с hot key), hive (scheduler — split/move/elect), coordinator (DTX — deterministic order для cross-tablet).bs-dc1, bs-dc2, bs-dc3, по диску на DC. Tablets пишут erasure-coded stripes сразу во все три.app — внешний клиент по gRPC / PG wire.
Edges: клиент бьёт в любой query-node, тот роутит к tablet leader по range. Tablets читают/пишут в BlobStorage напрямую. Координатор DTX подписан на оба query-node и оба participant-tablet. Hive подписан на все tablets (placement directives) и на DC2 (EC repair coordination).
Транзакция перевода 100 единиц с user id=42 на user id=1500. Эти rows живут на разных tablets (tablet-a и tablet-b). Query layer читает оба snapshot'а, координатор назначает global commit_ts, пишет deterministic log entry со списком участников и операций. Оба tablet применяют локально в одном порядке — без prepare-vote round и без TrueTime commit-wait. После применения каждый tablet пишет erasure-coded stripe (6+3) сразу в три DC. Latency intra-region ~20-30ms.
Ключевое: cross-tablet здесь — это не classic 2PC (blocking при failure coordinator, locks весь round-trip) и не Spanner-style TrueTime (требует атомных часов). YDB использует собственный протокол: deterministic ordering на уровне tablets, координатор только присваивает порядок.
orders таблица с sequential PK (UUID-v7) под нагрузкой 5K writes/s. Весь поток летит в один tablet-hot — типичный hot-tail антипаттерн. Hive scheduler видит metric (size=2.1GB > 1GB threshold, p99=80ms), принимает решение split по midpoint key. Split — metadata-only: BlobStorage уже распределён, blob'ы не копируются, просто создаются два tablet с новыми key-range и наследуемыми BS pointers. Freeze на ~50-100ms (новые writes queue'ются), потом query-nodes получают обновлённый routing table. Throughput 2x, p99 возвращается к 10ms. Прозрачно для приложения.
Урок сценария: даже на YDB sequential PK даёт hot tail. Для high-write таблиц используйте ULID или UUID-v4 на префиксе.
DC2 падает: power outage / network partition. На DC2 был leader tablet-a. BlobStorage write в bs-dc2 отваливается по timeout, follower elections через Paxos-like protocol (3-5s), follower на DC1 promoted to leader, term++. In-flight client получает retryable error и повторяет запрос — query routes к новому leader.
Кластер продолжает писать в degraded mode: EC 6+3 переживает потерю любого 1 DC, write идёт в 2 DC из 3, отсутствующие chunks реконструируются из parity при чтении. Latency tail растёт с 10ms до ~50ms, но availability сохраняется. Когда DC2 поднимается, background EC repair дочитывает stripes из DC1+DC3, восстанавливает локальные chunks; follower догоняет log и возвращается в кворум.
Граница: EC 6+3 переживает 1 DC failure. Для 2 DC failure нужен 6+4 (больше overhead) или standby cluster в другом регионе.
На query-1 есть две Architecture Decision Records — кликабельны прямо на ноде.
ADR-001: YDB vs Spanner vs CockroachDB. Три зрелых NewSQL-движка, но с разными trade-off'ами:
Решение: Spanner — если уже в GCP и нужна global consistency. Cockroach — multi-region OSS с Postgres-compat. YDB — Yandex Cloud, российский enterprise (152-ФЗ), multi-tenant SaaS с tables+topics в одной системе. Ни один из трёх — не для маленьких single-region apps (overhead не оправдан, берите Postgres) и не для heavy analytics (оптимизатор слабее ClickHouse / Snowflake).
ADR-002: Cross-tablet DTX vs classic 2PC vs TrueTime. Cross-tablet транзакция трогает несколько leaders на разных storage nodes. Варианты:
Решение: использовать YDB DTX, потому что (1) latency intra-DC ~20-30ms против ~50-80ms у 2PC, (2) нет hard-dep на специальное hardware (TrueTime), (3) hot tablet split не блокирует in-flight cross-tablet txn. Цена: протокол непортабелен, формальные доказательства correctness — внутренние Yandex publications, не peer-reviewed papers как Spanner/Calvin. Для строгой external consistency cross-DC — закладывайте latency budget на repl waits или возьмите Spanner.
Production sizing rules of thumb: 3-100+ nodes typical (тысячи — для Yandex internal). Throughput ~10-50K QPS на node, кластер масштабируется ~линейно. Latency ~5-15ms simple OLTP, cross-tablet ~20-50ms. Storage — до петабайт, EC снижает overhead с 3x до ~1.5x. Multi-DC по умолчанию 3-5 DC с automatic failover.
Внешние ссылки: https://ydb.tech/docs/, GitHub https://github.com/ydb-platform/ydb, YQL reference https://ydb.tech/docs/yql/reference/. Engineering deep-dives — Highload++ talks (Andrey Fomichev, "How YDB scales"), посты на Habr от Yandex teams.