Перейти к содержанию

D. Real-time Analytics

Walkthrough · Раздел03

Тип материала: учебный архитектурный сценарий. Не описывает систему конкретной компании.

Границы и версии

Kafka4.1 → Flink1.20.3 → versioned window results → ClickHouse25.8 → Dashboard. Результаты могут корректироваться; dashboard freshness/completeness contract явно отделён от финансового settlement. HYPOTHETICAL.

Data contracts

Input event имеет stable ID и business revision. Output key=(tenant,window_start,window_end,metric,generation), revision монотонна для результата в одной lineage, value=полный aggregate snapshot с units. Window partition immutable; equal key/revision означает одинаковый payload.

Input contract должен выбрать immutable facts либо entity upserts. Для immutable facts correction — отдельный adjustment fact с собственной identity. Для upserts keyed normalizer хранит прежнюю версию/вклад, отбрасывает stale/duplicate revision и retracts старый вклад перед добавлением нового; если изменилось attribution time, исправляются оба окна. Просто просуммировать amount каждой bet revision неверно. Bounded SQL examples ниже используют заранее уникальные immutable facts и не реализуют этот upsert normalizer.

State ownership и transaction boundaries

Владелец State / scope
Kafka Replayable raw/normalized history
Flink Window state/timers/dedup/checkpoints
ClickHouse Revisions и latest-result query
Dashboard Выбранные generation/watermark/completeness

Архитектура — HYPOTHETICAL

flowchart TB
  Kafka --> Flink[Event-time aggregate and corrections]
  Flink --> Revisions[Checkpoint-aware Kafka result transactions]
  Revisions --> CH[ClickHouse revision table]
  CH --> Latest[Latest per window and generation]
  Latest --> Dashboard[Dashboard with watermark]

Нормальная обработка по шагам

  1. Валидировать/нормализовать input, исключить semantic duplicates по согласованному horizon.

  2. Flink агрегирует keyed event-time windows и emits initial/corrected snapshots; результат changelog не является независимым additive fact.

  3. Flink публикует revisions через checkpoint-aware transactional Kafka result topic; CH consumer читает read_committed и сохраняет key/version/generation. Version counter входит в managed state. Неподтверждённые result transactions не видны consumer; после CH insert до offset commit возможен повтор той же immutable revision. Background merges не гарантируют немедленной уникальности.

  4. Query сначала latest per window/metric, затем SUM across independent windows. Нельзя суммировать raw versions или копить sumState MV над repeated snapshots без retract/correction protocol.

  5. Late within policy увеличивает revision; late after cleanup попадает в controlled recompute/backfill generation.

  6. Dashboard показывает generation и watermark/completeness; финансовый закрытый отчёт использует validated cut, не случайно текущий partial view.

sequenceDiagram
  participant Source as Source or caller
  participant Kafka as Kafka retained log
  participant Sink as Processing worker
  participant Target as Target state
  Source->>Kafka: Immutable event or business correction
  Kafka->>Sink: Flink updates event-time window
  Sink->>Kafka: Commit versioned aggregate through checkpoint-aware Kafka sink
  Kafka->>Target: CH consumer reads committed result and inserts revision
  Target-->>Source: Dashboard selects latest revision
  Note over Sink,Target: Incremental MV over raw snapshots<br/>would overcount

Failure / recovery sequence — HYPOTHETICAL

sequenceDiagram
  participant Source as Source or caller
  participant Kafka as Kafka retained log
  participant Sink as Processing worker
  participant Target as Target state
  Kafka->>Sink: CH consumer reads committed corrected revision V2
  Sink->>Target: Insert V2 succeeds
  Note over Sink,Kafka: CH consumer crashes before result offset commit
  Kafka->>Sink: Replay the same committed result V2
  Sink->>Target: Duplicate V2 with identical payload
  Target-->>Source: Latest query remains correction-aware before merge

Replay / backfill protocol

Retain raw + code/reference-data versions. Recompute historical scope в отдельной generation, сверить distinct keys/window totals, затем переключить dashboard pointer. Source retention и late policy должны покрывать нужный scope; deleting versions не должен воскресить older stale result.

При прямом nontransactional Flink→CH write нельзя предполагать, что rollback checkpoint сохранит тот же revision/payload для промежуточных emissions: порядок interleaving может измениться. Result-topic protocol выше закрывает именно публикацию committed revisions при своих assumptions; его runtime validation ещё NOT_RUN.

Monitoring и alerting

Flink watermark/state/checkpoint, output Kafka lag, CH parts/merge/mutation queues, invalid revisions/equal-version conflicts, query rows/bytes и dashboard source-age. Проверять business completeness отдельно от successful insert.

Trade-offs и альтернативы

Preaggregation экономит query IO, но усложняет corrections. Query-time latest дороже raw sum, зато соответствует revisions. Альтернативы — append-only finalized windows при доказанном lateness contract либо periodic full validated snapshot.

Типичные ошибки проектирования

Считать всю цепочку одной transaction; терять stable identity/versions; скрывать late/rejected scope; смешивать backfill и live generations; делать external financial effect во время технического replay.

Вопросы на собеседовании

Какая E2E guarantee доказана этой схемой? Сама схема ничего не доказывает. Нужны реализованные source/state/sink protocols и experiments для указанных failure points; фактически выполненные проверки перечислены в отчёте.

Практические упражнения

Воспроизведите failure sequence в изолированном runtime и сохраните source positions, target state, count/key/amount reconciliation и recovery evidence. До этого distributed guarantee остаётся документированной моделью.

Дополнительные источники и примеры

Протокол проверок (архив рабочего проекта) · Журнал ограничений (архив рабочего проекта).