GH GambleHub

Przechowywanie szeregów czasowych

1) Dlaczego oddzielna architektura dla serii czasowych

Serie czasowe to sekwencje par (znacznik czasowy, wartość) z tagami (etykiety), które charakteryzują się:
  • Wysoka prędkość nagrywania (połknięcie) i częstotliwość.
  • Odczytuje według zakresów czasu (skanowanie + agregaty/funkcje okna).
  • Wybuchowa kardynalność z powodu kombinacji znaczników.
  • Konieczność zatrzymania (ograniczenia trwałości) i obniżenia (kompresja czasu).
  • Stąd - specjalny model pamięci masowej, formaty kompresji i protokoły żądań.

2) Model danych i metryki kontraktowe

2. 1 Nazwy i tagi

metric_name: pojedynczy czasownik/rzeczownik ('http _ requests _ total', 'cpu _ usage _ seconds _ total').
etykiety: klucze atrybutów ('job', 'instance', 'dc',' pod ',' status ',' method ').
Niezmienne: nie zmieniaj semantyki nazwy, dodaj wersje ('metric _ v2') z niezgodnymi zmianami.

2. 2 Rodzaje rzędów

Skrajnia, licznik, histogram/podsumowanie, zdarzenie/rozpiętość.
Dla finansów/gęstości - Ustalanie jednostek i agregacji (sumowane/uśrednione).

2. 3 Polityka zatrzymywania i Rollup

Gorący szczegół (sekundy/1-10 min) → ciepłe jednostki (5m/1h) → zimno (1d/1w).
Dla licznika - szybkość przechowywania/agregaty deriv.

3) Ścieżka nagrywania: odbiór, bufor, kompaktowy

3. 1 Rurociąg połykający

Scrape (pull, Prometheus) lub push (OTLP/StatsD/Graphite), często za pośrednictwem bramy/agenta.
Buforowanie w log WAL (write-ahead), a następnie kompresowanie do segmentów/bloków (architektura podobna do LSM).
Sortowanie partii i czasu zwiększa kompresję i szybkość.

3. 2 Obsługa out-of-order i przyjmuje

Okno tolerancji (okno opóźnienia, na przykład 5-15 min) + zasady: „upsert | upsert | keep-last”.
Deduplikacja przez '(series_id, timestamp)' z wersją lub „wygrywa ostatni rekord”.

3. 3 Kompresja

Delta-of-delta for timestamps, Gorilla/XOR for float, RLE i varint for integers, słownik dla tagów.
Optymalny rozmiar bloku („kawałek”) punktów 1-8K jest kompromisem pomiędzy IOPS i procesorem.

4) Systemy przechowywania: TSDB vs SQL/kolumny

4. 1 Dedykowany TSDB

Prometeusz (lokalna, krótka retencja, PromQL, remote_write).
VictoriaMetrics/M3/InfluxDB - skalowanie poziome, długa retencja, zdalny odczyt.
Formaty bloków są zoptymalizowane pod kątem skanowania zakresu + agregacji przetargowych.

4. 2 Silniki relacyjne/kolumnowe

TimescaleDB (PostgreSQL): nadciśnienia, kawałki według czasu/przestrzeni, kruszywa ciągłe.
ClickHouse: MergeTree/TTL/zmaterializowane widoki, doskonała kompresja i agregacja czasu.
Wybór - przez ekosystem zapytania (SQL vs PromQL), przyłączyć/BI wymagania i umiejętności operacyjne zespołu.

5) Schemat i przykłady

5. 1 TimescaleDB: nadmiar + kruszywo ciągłe

sql
CREATE TABLE metrics_cpu(
ts timestamptz NOT NULL,
host text NOT NULL,
dc text NOT NULL,
usage double precision NOT NULL,
PRIMARY KEY (ts, host, dc)
);
SELECT create_hypertable('metrics_cpu', by_range('ts'), chunk_time_interval => interval '1 day');

-- Continuous unit (5 minutes)
CREATE MATERIALIZED VIEW cpu_5m
WITH (timescaledb. continuous) AS
SELECT time_bucket('5 minutes', ts) AS ts5m, host, dc, avg(usage) AS avg_usage
FROM metrics_cpu GROUP BY 1,2,3;

-- Politicians
SELECT add_retention_policy('metrics_cpu', INTERVAL '14 days');
SELECT add_retention_policy('cpu_5m',   INTERVAL '180 days');

5. 2 ClickHouse: agregowanie pamięci

sql
CREATE TABLE metrics_cpu (
ts DateTime,
host LowCardinality(String),
dc LowCardinality(String),
usage Float32
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(ts)
ORDER BY (host, dc, ts)
TTL ts + INTERVAL 14 DAY
SETTINGS index_granularity = 8192;

-- Rollup in hourly detail
CREATE MATERIALIZED VIEW cpu_1h
ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(ts)
ORDER BY (host, dc, ts)
POPULATE AS
SELECT toStartOfHour(ts) AS ts, host, dc, avg(usage) AS usage
FROM metrics_cpu GROUP BY ts, host, dc;

5. 3 Prometeusz/VictoriaMetrics: remote_write

yaml global:
scrape_interval: 15s remote_write:
- url: http://vminsert:8480/insert/0/prometheus/api/v1/write

6) Kardynalność: jak nie „wysadzić” magazynu

6. 1 Zasady

Kardynalność etykiety limitowanej (liczba unikalnych wartości). Nie włączaj 'user _ id',' request _ id', 'trace _ id'.
Normalizacja „multi-valued” tagi (kategorie → kody).
Użyj typów LowCardinality (w CH), słowników/etykiet drzew (w TSDB).

6. 2 Kontrole i wpisy

Mierniki: 'series _ count',' label _ values {label} ', top-N' drogie 'wiersze.
Zapisz zasady niepowodzenia, gdy limit kardynalności zostanie przekroczony na najemcę/zadanie.

6. 3 Historie/Histogramy

Dla wysokiej kardynalności, lepiej jest przechowywać kruszywa (wiadra histogramowe) i pre-rollup; kwantyle do obliczania online na agregatach.

7) Zatrzymywanie, obniżanie i magazynowanie wielopoziomowe

7. 1 Polityka

Gorący: 3-30 dni szczegółów sekundy/minuty.
Ciepło: 90-365 dni kruszywa 5m/1h.
Zimno: lata agregatów dziennych, archiwum w magazynie obiektów (S3/Glacier) z parkietem.

7. 2 Technicy

Ciągłe agregaty (skala czasowa), zmaterializowane widoki (CH), zadania retencji + rollup (Victoria/M3/Influence).
Magazyn wielopoziomowy: „gorące bloki” lokalnie, „zimno” w obiekcie z lokalnym buforem.

8) Zapytania i języki

8. 1 PromQL (przykład)

promql rate(http_requests_total{job="api",status=~"5.."}[5m])

Szukasz błędu 5xx API.

8. 2 agregaty SQL według okien

sql
SELECT time_bucket('1h', ts) AS hour,
dc, avg(usage) AS avg, max(usage) AS pmax
FROM metrics_cpu
WHERE ts >= now() - interval '24 hours'
GROUP BY 1,2 ORDER BY 1;

8. 3 Anomalie (szkic)

Z-score/ESD według statystyk okien, STL rozkład sezonowości; przechowywać wyniki w oddzielnym wierszu 'anomalia = 1/0'.

9) Integracja i protokoły

OTLP (OpenTelemetry): mierniki/ścieżki/dzienniki, eksporterzy na agentach (otel-collector) → TSDB/clickhouse/object.
StatsD/Graphite: proste liczniki/zegary; proxy to edge, a następnie konwersja do jednego formatu.
Kafka/NATS: bufor do wybuchów, replika do zasypki; konsumenci piszą batchami.

Przykład Kafka → ClickHouse (pseudo):
text kafka(topic=metrics) -> stream processor (normalize/tags) -> CH INSERT INTO metrics_cpu FORMAT RowBinary

10) Dostępność, HA i Federacja

Replika/TSDB HA par lub Prometheus federacji (region → poziom globalny).
Zdalny odczyt/zapis do długotrwałego przechowywania i scentralizowanych desek rozdzielczych.
Shard-by-label/time: jednolity rozkład spożycia, lokalizacja przez 'dc/najemca'.

11) W przedmiocie obserwowalności samego składowania

11. 1 Metryka

Połknięcie: 'próbki/sec', 'append _ latency', 'wal _ fsync _ ms'.
Мранений: 'blocks _ count',' compaction _ queue _ len ',' chunk _ compression _ ratio '.
Саброса: 'query _ qps', 'scan _ bytes', 'p95/p99 _ latency', 'alloc _ bytes'.
Kardynalność: 'series _ count', najwyższe etykiety.

11. 2 SLO

„p99 opóźnienia dla zakresu 1h ≤ 200ms przy QPS ≤ 500”.

"Kropla do spożycia ≤ 0. 01% przy wybuchu przed próbkami X/s"

„Zaległości zagęszczania <10 min”.

11. 3 Wpisy

Wzrost 'series _ count'> Y %/godz.
Kolejka kompresji/spłukiwanie> próg.
Дола-of-order> N%, dedup/late-drops.

12) Bezpieczeństwo i wielopoziomowość

Izolacja przez „najemcę” (etykieta w klawiszach, poszczególne tabele/bazy danych, kwoty).
Oczyszczanie etykiet (zakaz PII), kontrola wielkości/wartości.
Szyfrowanie „w spoczynku” i w transporcie, audyt dostępu do „wrażliwych” mierników.

13) Praktyki operacyjne

Rozgrzewka i zimny start: pin „gorących” bloków w pamięci podręcznej, prefetch ostatnich godzin N.
Zasypka: poszczególne rurociągi o niskim priorytecie, nie mieszać z online.
Wersioning schematu: migracje z równoległym zapisem (dual-write) i kolejnym przełącznikiem.
Budżet na składowanie: kontrola 'cost _ per _ TB _ month' + prognoza wzrostu kardynalności.

14) Anty-wzory

Tagi o wysokiej kardynalności (user_id, uuid) → eksplozja rzędów.
„Wieczne” rzędy bez zatrzymywania → niekontrolowany wzrost.
Non-butching/sortowanie nagrywanie → słaba kompresja i burza IOPS.
Wymieszaj OLTP i długie skany na tej samej puli dysków.
Brak polityki pozasądowej → duplikaty i wzdęcia.
Histogramy z setkami wiader → koszt × 10 bez korzyści.

15) Lista kontrolna wdrażania

  • Określić wskaźniki, ich rodzaje i jednostki; naprawić kontrakt na nazwę/etykietę.
  • Wybierz silnik (TSDB vs SQL/Column) i język zapytania (PromQL/SQL).
  • Projekt retencji/rollup (gorący/ciepły/zimny) i ILM.
  • Konfiguracja ingest: WAL/partie/sortowanie, okna poza zamówieniem.
  • Włącz kompresję (delta-of-delta/XOR/RLE), optymalne kawałki.
  • Kardynalność kontroli: kwoty, wpisy, polityka opt-out.
  • Konfiguracja HA/federacji i zdalnego zapisu/odczytu.
  • Deski rozdzielcze SLO i mierniki pamięci masowej (połknięcie/zapytanie/przechowywanie).
  • Polityka izolacji bezpieczeństwa/najemcy i brak PII w etykietach.
  • Regularny „dzień gry”: zasypka, utrata węzła, przepięcie.

16) FAQ

P: Co wybrać do monitorowania infrastruktury: Prometheus lub ClickHouse/Timescale?
Odp.: Do monitorowania pochodzenia i PromQL - Prometheus + przechowywanie długoterminowe (Victoria/M3). Dla scenariuszy BI/magazynu i SQL - Timescale/ClickHouse.

P: Jak przechowywać kwantyle bez ciężkich podsumowań?
Odp.: Użyj histogramu ze schludnymi wiadrami i oblicz kwantyle na żądanie; lub t-digest/CKMS w kruszywach.

P: Jak radzić sobie z nieporządkiem?
Odp.: Wprowadź okno tolerancji (5-15 min) i deterministyczną politykę dedup; dla telemetrii z mobilnej/krawędzi - okno jest szersze.

P: Kiedy potrzebny jest rollup?
Odp.: Zawsze> 30-90 dni: agregaty zmniejszają rozmiar × 10-100 i przyspieszają analitykę.

P: Czy możliwe jest mieszanie dzienników i mierników?
Odp.: Przechowywać osobno (formaty/zapytania są różne). Do korelacji należy stosować Przykładowy/TraceID i deski rozdzielcze, ale nie dodawać wszystkiego do jednej tabeli.

17) Kwoty całkowite

Efektywne przechowywanie serii czasowych to kontrakt metryczny + dyscyplina znaczników, właściwe spożycie (WAL/zagęszczenie), kompresja i polityka retencji/rollup. Dodaj kontrolę kardynalności, NA/federację i obserwowalność samego sklepu - a otrzymasz przewidywalny p95, rozsądny koszt od miesięcy do lat i opór gwałtowny.

Contact

Skontaktuj się z nami

Napisz do nas w każdej sprawie — pytania, wsparcie, konsultacje.Zawsze jesteśmy gotowi pomóc!

Telegram
@Gamble_GC
Rozpocznij integrację

Email jest wymagany. Telegram lub WhatsApp są opcjonalne.

Twoje imię opcjonalne
Email opcjonalne
Temat opcjonalne
Wiadomość opcjonalne
Telegram opcjonalne
@
Jeśli podasz Telegram — odpowiemy także tam, oprócz emaila.
WhatsApp opcjonalne
Format: kod kraju i numer (np. +48XXXXXXXXX).

Klikając przycisk, wyrażasz zgodę na przetwarzanie swoich danych.