06 · Данные для ML6.1–6.4 · Потоки, батч и признаки6.3.3сложный

Ограничения Spark и когда не использовать

Зачем это нужно

Spark мощный, но не универсальный. Команды иногда «тащат Spark везде» — и получают медленный inference, дорогой кластер и сложный ops. MLOps-инженер должен уметь сказать: «здесь Spark — да, здесь — pandas/DuckDB/Kafka Streams/GPU job».

Этот урок — про границы применимости и типичные ошибки, чтобы вы не строили архитектуру против инструмента.

Основные идеи

Spark силён когда:

  • Data не помещается в RAM одной машины (десятки GB – PB).

  • Нужны распределённые joins/aggregations на кластере.

  • Batch pipeline уже на JVM/Hadoop ecosystem.

  • Единый код batch + streaming (Structured Streaming).

Spark слаб / избыточен когда:

Сценарий Лучшая альтернатива Почему
1 GB CSV для учебного проекта pandas, polars, DuckDB Overhead cluster > benefit
p99 latency 50 ms online scoring Dedicated inference server (Triton, MLServer) Spark latency + JVM warmup
Deep learning train на GPU PyTorch/JAX native, Horovod Spark MLlib DL limited
Complex event processing ms-level Flink, Kafka Streams Spark micro-batch seconds+
Ad-hoc SQL аналитика Trino, ClickHouse Interactive faster

Latency floor. Structured Streaming micro-batch — обычно секунды, не миллисекунды. Для sub-second features — Flink или custom consumer.

Operational cost. Spark cluster = driver + N executors + shuffle storage + monitoring. На маленьких данных один fat Pod с polars часто дешевле и проще в K8s.

Python UDF penalty. Row-at-a-time Python UDF ломает vectorization Catalyst — медленно. Prefer Spark SQL functions, pandas UDF (vectorized), или pre-process outside Spark.

Small file problem. Spark пишет много part-000xx.parquet. Чтение миллионов files убивает performance. Нужен periodic compaction job (coalesce / repartition before write).

Skew и stragglers. Hot key в groupBy → один task обрабатывает 80% data. Salting, adaptive skew join (Spark 3.x) — но debugging сложный для новичков.

State in Spark Streaming. Stateful aggregations (windows) требуют checkpoint на durable storage. Потеря checkpoint = tricky recovery. Ops burden выше, чем у stateless batch.

ML model format friction. Spark MLlib Pipeline ≠ sklearn ≠ ONNX. Конвертация — extra step. Многие команды: Spark только до train export; serving — другой stack (модуль 7).

Decision matrix (упрощённая).

Размер данных < 10 GB и команда маленькая? → pandas/polars Нужен online REST inference? → KServe/Triton, не Spark Batch scoring 100M rows nightly? → Spark или SQL warehouse + export Streaming features < 1s? → Flink/Kafka consumer Streaming features 10s–1min OK? → Spark Structured Streaming

Когда Spark + ML всё же правильный выбор. Единая платформа data engineering уже на Spark; feature jobs 500M+ rows; batch scoring в DWH integration; команда имеет Spark SRE expertise.

Как это выглядит на практике

Case study A — ошибка. Команда сделала REST API поверх Spark job, который collect() score для одного user — cold start 30s, p95 8s. Fix: precomputed features in Redis + LightGBM in MLServer.

Case study B — правильно. Nightly 80M users batch churn scores → Spark writes to scores_daily table → CRM reads via SQL. Latency не критична; Spark parallelizes predict UDF (still watch UDF cost).

Case study C — компромисс. Spark готовит features; train на sampled 5M rows на GPU node; serving ONNX on Triton. Каждый инструмент — на своём этапе.

ADR trigger (см. 6.4.3). Если спор «нужен ли Spark для feature job» — фиксируйте: data volume, SLA, team skills, existing infra.

Что сделать после занятия

  • Для учебного проекта (< 1 GB data) обоснуйте, почему Spark не нужен.

  • Придумайте сценарий, где batch Spark scoring уместен (3 предложения).

  • Заполните decision matrix для вашего capstone: какой объём, какой latency?

Официальные материалы