System Design Cases
Time-series databases
Time-series databases — Prometheus + VictoriaMetrics architecture with high-cardinality scrape ingestion, PromQL range query, downsampling pipeline (1m -> 5m -> 1h -> 1d) with retention drops, and ADR comparing Prometheus / InfluxDB / TimescaleDB / ClickHouse / Mimir for a Kubernetes platform with 3M active series.
Time-series databases: series identity, ingest, retention and late data
TSDB — это не «обычная БД плюс timestamp». Series identity определяет index cardinality, event time определяет placement, а retention/compaction меняют физические blocks. Корректный дизайн отдельно задаёт durability ingest, обработку late/out-of-order samples и query resolution.
Корректная модель
- Series обычно определяется metric name плюс полный набор label/tag values; timestamp не заменяет series key.
- WAL/head, immutable blocks, index и remote storage — разные durability и query boundaries.
- Out-of-order и duplicate semantics зависят от engine/configuration и должны быть частью ingest API contract.
- Retention cleanup и compaction требуют disk headroom; logical retention не равна жёсткому мгновенному byte cap.
Границы и компоненты
| Компонент | Ответственность |
|---|---|
| Metric Producers | Отправляют timestamped samples и стабильный набор dimensions. |
| Ingest Gateway | Проверяет schema, timestamp bounds, tenant limits и idempotency identity. |
| WAL and Mutable Head | Защищает незакомпакченные samples от process crash в пределах настроенной durability. |
| Series and Label Index | Находит series по dimensions; его стоимость растёт с cardinality. |
| Immutable Time Blocks | Хранит compressed chunks, metadata и tombstones по time range. |
| Compactor and Retention | Создаёт larger blocks, удаляет fully expired blocks и учитывает temporary disk headroom. |
| Range Query Engine | Планирует range scan, downsampling и aggregation без обещания fixed latency. |
Сценарии
Durable ordered ingest
Valid samples enter the WAL/head before acknowledgement and later become immutable blocks; that ordering is an engine-specific durability contract, not a claim that every TSDB replicates.
Проверяемый исход: Success is acknowledged only at the configured durable boundary; compaction is asynchronous.
Late and duplicate sample
A retry or delayed producer can target an older time range. The gateway applies the documented engine policy: reject, overwrite by identity, or accept into a correction path.
Проверяемый исход: No silent double count: duplicate identity and lateness policy are observable and deterministic.
Retention and compaction headroom
Compaction temporarily keeps inputs and outputs. Retention removes fully expired blocks in background rather than promising an exact byte ceiling at every instant.
Проверяемый исход: Disk alerting includes WAL/head and compaction overlap; deletion is not treated as an immediate space guarantee.
Cardinality overload
Unbounded user-controlled labels create new series and pressure the index and memory even when samples per second look acceptable.
Проверяемый исход: Tenant limits reject or quarantine dangerous dimensions before the index becomes the global bottleneck.
Failure, concurrency и replay checklist
- Ограничивать label cardinality до записи в index.
- Не удалять WAL при recovery без явного принятия data loss.
- Дедуплицировать по документированной identity, а не только по wall-clock timestamp.
- Проверять restore из snapshot/remote copy; local Prometheus storage сам по себе не clustered.
Формулы, units и допущения
- Размерность: bytes = samples/s × seconds retained × measured bytes/sample; index, WAL, replicas, compaction overlap и free-space reserve считаются отдельно.
- Учебный пример: 100 000 samples/s × 86 400 s/day × 30 days = 259.2 billion samples. Даже 2 B/sample дают 518.4 GB только для sample payload; это не полный disk budget.
- Rate вычисляется из sample deltas и elapsed event time с учётом counter reset; нельзя делить одно значение counter на uptime и называть это универсальным rate.
Числа выше — учебные inputs или размерностные формулы. Их нельзя выдавать за benchmark или SLA конкретного продукта.
Связанные темы
Первичные источники
- https://prometheus.io/docs/prometheus/latest/storage/
- https://prometheus.io/docs/practices/instrumentation/
- https://github.com/prometheus/prometheus/blob/main/tsdb/docs/format/README.md
- https://www.vldb.org/pvldb/vol8/p1816-teller.pdf
Scope note
Диаграмма показывает причинные границы и recovery contracts, а не скрытую реализацию конкретного managed-сервиса. Любая stronger guarantee действует только в явно названной transaction/checkpoint/acknowledgement boundary.