praca_magisterska/pytania/questions/pytanie_20_30.md

11 KiB
Raw Blame History

PYTANIE 20/30: Analityka danych strumieniowych

Rozwiązania analityczne na danych strumieniowych.


Tło pojęciowe — słowniczek

Dane strumieniowe (streaming data) — ciągły, potencjalnie nieskończony przepływ zdarzeń (events) przychodzących w czasie rzeczywistym. Przykłady: kliknięcia użytkowników, odczyty sensorów IoT, transakcje bankowe, logi serwerów. W odróżnieniu od danych wsadowych (batch): nie możesz „poczekać na wszystkie" — musisz analizować na bieżąco.

Batch:      [cały zbiór] → analiza → wynik     (minuty/godziny)
Streaming:  event → event → event → ...→ analiza ciągła    (ms/sekundy)

Strumień (stream) — abstrakcja: nieograniczona (unbounded) sekwencja zdarzeń, każde ze stemplem czasowym. Musisz przetwarzać „w locie" — nie mieścisz wszystkiego w pamięci.


Event Time vs Processing Time:

  • Event Time — moment GDY zdarzenie nastąpiło (np. kliknięcie o 14:00:05)

  • Processing Time — moment GDY system przetwarza zdarzenie (np. o 14:00:07)

  • Różnica wynika z opóźnień sieciowych. Zdarzenia mogą przychodzić out-of-order (pozamiejscowe).

    Zdarzenie A (event time 14:00:01) → dociera o 14:00:05 Zdarzenie B (event time 14:00:03) → dociera o 14:00:04 B dociera PRZED A, mimo że A było wcześniej!

Watermark — znacznik postępu: „z dużym prawdopodobieństwem nie przyjdą już zdarzenia z event time < W". Pozwala systemowi zdecydować, kiedy zamknąć okno i wyemitować wynik. Zdarzenia po watermarku = „late data" (spóźnione).


Okno czasowe (window) — mechanizm grupowania zdarzeń w strumienia w skończone porcje do analizy:

Tumbling window (okno przerzutne) — stały rozmiar, rozłączne. Np. „liczba kliknięć co 5 minut".

|---5min---|---5min---|---5min---|
[events A] [events B] [events C]   ← 0 nakładania

Sliding window (okno przesuwne) — stały rozmiar + krok przesunięcia. Nakładają się. Np. „średnia z 10 min, co 1 min".

|----10min----|
   |----10min----|
      |----10min----|              ← nakładanie

Session window (okno sesji) — dynamiczny rozmiar, oparte na aktywności. Nowa sesja po przerwie (gap). Np. „sesja użytkownika: od pierwszego kliknięcia do 30 min nieaktywności".

Global window — jedno okno na cały strumień. Trigger decyduje kiedy wyemitować wynik.


True streaming vs Micro-batch:

  • True streaming — przetwarzanie event-by-event. Niższa latencja. Kafka Streams, Flink.
  • Micro-batch — grupowanie zdarzeń w małe paczki (np. co 100ms) i przetwarzanie batch. Spark Streaming. Prostsza semantyka, ale wyższa latencja.

Kafka Streams — biblioteka (nie klaster!) do przetwarzania strumieni Kafka. Działa w procesie aplikacji Java. Niska latencja, exactly-once. Stateful processing (windows, joins).

Apache Flink — rozproszony silnik do true streaming. Bardzo niska latencja (<10ms). Natywne wsparcie event time, windows, stateful processing. Exactly-once. Deployment jako klaster.

Spark Streaming — rozszerzenie Apache Spark. Model micro-batch (~100ms+). Średnia latencja, ale korzysta z ekosystemu Spark (SQL, ML). Exactly-once.


Algorytmy strumieniowe (probabilistyczne):

HyperLogLog — estymacja liczby unikalnych elementów (cardinality). Zużywa O(1) pamięci (~1.5 KB) niezależnie od liczby elementów. Błąd ~2%.

100 mln unikalnych URL-i → HyperLogLog odpowiada "~100 mln ± 2%"
Pamięć: 1.5 KB zamiast ~800 MB (hash set)

Count-Min Sketch — estymacja częstości elementów. Macierz d×w z hashami. Gwarantuje overestimates (nigdy nie zaniży). O(1) per query/update.

"Ile razy pojawił się IP 192.168.1.1?" → CMS: ~4523 (± ε·N)

Reservoir Sampling — równomierne próbkowanie k elementów ze strumienia o nieznanym rozmiarze n. Każdy element ma szansę k/n. O(k) pamięci.

Late data strategies:

  • Drop — odrzuć spóźnione zdarzenia
  • Recompute — przelicz okno ponownie
  • Side output — przekieruj do osobnego strumienia do ręcznej analizy
  • Allowed lateness — czekaj dodatkowy czas przed zamknięciem okna

Rozwiązania analityczne — przegląd

Rozwiązanie analityczne na strumieniu = odpowiedź na pytanie biznesowe w czasie rzeczywistym, gdy dane przychodzą ciągle i nie można ich wszystkich zapamiętać. Trzy filary: windowing (jak grupować), platformy (gdzie przetwarzać), algorytmy probabilistyczne (jak liczyć w O(1) pamięci).


Rozwiązanie 1 — Analityka okienna (Windowing)

Problem: strumień jest nieskończony, a analiza wymaga skończonej porcji danych. Okno wyodrębnia fragment strumienia do obliczenia agregatu (count, sum, avg, max).

4 typy okien:

Okno Rozmiar Nakładanie Kiedy użyć
Tumbling stały rozłączne raporty okresowe: „kliknięcia co 5 min"
Sliding stały + krok nakładające średnie kroczące: „avg(10 min) co 1 min"
Session dynamiczny (gap) rozłączne per klucz sesje użytkowników: „aktywność do 30 min przerwy"
Global cały strumień trigger-based: „emituj po N zdarzeniach"

Przykład — Tumbling window (fraud detection):

Strumień transakcji bankowych, okno = 1 minuta:
[14:0014:01] → 3 transakcje z karty X → OK
[14:0114:02] → 47 transakcji z karty X → ALERT! (>10 = podejrzane)

Przykład — Sliding window (monitoring SLA):

Okno = 5 min, krok = 1 min (nakładanie):
t=14:05 → avg latency [14:0014:05] = 120ms ✓
t=14:06 → avg latency [14:0114:06] = 340ms ✗ → alert

Event Time vs Processing Time:

  • Okna na event time = poprawne biznesowo (kiedy zdarzenie faktycznie nastąpiło)
  • Okna na processing time = prostsze, ale podatne na out-of-order delivery
  • Watermark rozwiązuje problem: „z prawdopodobieństwem ~100% nie przyjdą zdarzenia z event time < W"

Rozwiązanie 2 — Platformy przetwarzania strumieniowego

Cecha Kafka Streams Apache Flink Spark Streaming
Model event-by-event event-by-event micro-batch (~100ms)
Deployment library (w JVM) klaster klaster
Latencja ~110 ms < 10 ms 100 ms sekundy
Exactly-once tak (Kafka TXN) tak (checkpointing) tak (WAL)
State management RocksDB local RocksDB + checkpoints in-memory/external
Okna tumbling, sliding, session wszystkie + custom tumbling, sliding
Use case transformacja Kafka → Kafka złożona analityka real-time ETL z ekosystemem Spark

True streaming vs Micro-batch — co wybrać?

True streaming (Flink, Kafka Streams):
  Latencja:  < 10 ms    ← trade fraud, click tracking
  Semantyka: event-by-event
  Złożoność: wyższa (watermarks, state, exactly-once)

Micro-batch (Spark Streaming):
  Latencja:  ~100 ms  sekundy
  Semantyka: mini-batch (prostsza, batch-like API)
  Ekosystem: Spark SQL, MLlib → łatwa integracja z ML

Architektura Lambda vs Kappa:

Lambda: [batch layer (Spark)] + [speed layer (Flink)] → merge
        Dwa systemy, dwa kody — skomplikowane ale pewne

Kappa:  [streaming only (Flink/Kafka)] → replay z Kafka
        Jeden system — prostsze, ale replay = I/O koszt

Rozwiązanie 3 — Algorytmy probabilistyczne (Sketches)

Problem: na strumieniu nie zmieścisz WSZYSTKICH danych w pamięci. Algorytmy probabilistyczne dają przybliżone odpowiedzi w O(1) pamięci z gwarantowanym błędem.

Algorytm Pytanie Pamięć Błąd Przykład
HyperLogLog „Ile unikalnych?" ~1.5 KB ~2% unique visitors na stronie
Count-Min Sketch „Ile razy element X?" d×w counters ε·N (overestimate) częstość IP w logach
Bloom Filter „Czy element X był?" m bitów false positives, 0 false neg cache: „czy URL widziany?"
Reservoir Sampling „Losowa próbka k z n?" O(k) dokładna (nie przybliżona) próbka logów do debugowania
T-Digest „Jaki percentyl?" O(δ) <1% na ogonach p99 latency monitorowanie

Dlaczego HyperLogLog zużywa O(1)?

Idea: hashuj każdy element, licz pozycję pierwszego bitu 1.
Jeśli widzisz dużo zer na początku → prawdopodobnie dużo unikalnych.

100 mln unikalnych URL-i:
- HashSet: ~800 MB pamięci (8 bajtów × 10⁸)
- HyperLogLog: 1.5 KB pamięci, odpowiedź ~100 mln ± 2%
- Oszczędność: 500 000× mniej pamięci!

Count-Min Sketch — jak działa:

Macierz d wierszy × w kolumn (np. 5 × 2048), d funkcji hashowych.
Insert("X"): dla każdego hash h_i, zwiększ cell[i][h_i("X")]++
Query("X"):  min over i of cell[i][h_i("X")]
Gwarancja: nigdy nie ZANIŻY (overestimate, no underestimate)

Rozwiązanie 4 — Obsługa opóźnień i spójność

Problem late data: zdarzenie z event time 14:00:01 przychodzi o 14:00:30, gdy okno [14:0014:05] już zamknięte.

Strategia Opis Trade-off
Drop odrzuć spóźnione proste, ale utrata danych
Allowed lateness czekaj dodatkowy czas (np. +5 min) wyższe zużycie pamięci
Recompute przelicz okno z nowym zdarzeniem poprawne ale kosztowne
Side output przekieruj late events do osobnego strumienia elastyczne, ręczna analiza

Exactly-once semantics — gwarancja, że każde zdarzenie wpływa na wynik dokładnie raz, mimo awarii:

  • At-most-once — mogą zginąć (szybkie, proste)

  • At-least-once — mogą się zduplikować (retry)

  • Exactly-once — żadnych duplikatów ani strat (checkpoint + transakcje, kosztowne)

    Flink: distributed snapshots (algorytm Chandy-Lamport) → checkpoint co N ms Kafka Streams: transakcje Kafka (idempotent producer + TX coordinator) Spark: WAL (Write-Ahead Log) + idempotent sinks


Rozwiązanie 5 — CEP (Complex Event Processing)

Wykrywanie złożonych wzorców w strumieniach zdarzeń. Reguły definiowane deklaratywnie.

Pattern: "Jeśli 3 nieudane logowania z tego samego IP w ciągu 5 minut,
         a potem udane logowanie z INNEGO IP → alert: konto przejęte"

Flink CEP:
Pattern.<LoginEvent>begin("fails")
    .where(event -> !event.isSuccess())
    .times(3).within(Time.minutes(5))
    .next("success")
    .where(event -> event.isSuccess())

Zastosowania: fraud detection, cybersecurity, monitoring IoT, trading algorytmiczny.

Etymologia

Flink — niem. „flink" = zwinny/szybki (TU Berlin, 2014). Spark — „iskra"; Matei Zaharia (UC Berkeley, 2012). HyperLogLog — Philippe Flajolet et al. (2007); „Hyper" = ulepszenie LogLog; „LogLog" = zużywa log(log(n)) pamięci. Count-Min Sketch — Cormode & Muthukrishnan (2005); „sketch" = probabilistyczny skrót danych. Reservoir Sampling — Jeffrey Vitter (1985); „reservoir" = stały zbiornik prób. Watermark — znacznik postępu czasu zdarzeń w strumieniu.

Jak zapamiętać

  • 4 okna: „TSSG" — Tumbling, Sliding, Session, Global
  • Flink = szybki (true streaming), Spark = safe (micro-batch)
  • HyperLogLog = „ile unikalnych?" z kilobajtem pamięci