Покупка произошла раньше, чем поступила в обработку. Объясняем временную границу Spark, отличие от часов на стене и компромисс между опозданиями и хранением состояния.
Время покупки и время получения различаются
Представим условную сеть касс. Покупка произошла в десять утра, но касса временно потеряла связь и отправила запись позже. Если считать выручку по времени покупки, событие относится к прошлому интервалу. Расчёт должен решить, можно ли ещё дополнить его итог или прежний интервал уже завершён.
Spark Structured Streaming обрабатывает поступающие сведения и умеет поддерживать расчёты по времени событий. Watermark называют временной границей, связанной с допустимым запаздыванием. Чтобы понять её назначение, удобно спросить: какие прошлые итоги ещё могут измениться и как долго расчёту нужно хранить сведения о них? Это отдельный вопрос от самого факта задержки источника.
Граница связана с продвижением событий
В описании временной границы Apache Spark она связывается с наибольшим увиденным временем событий и заданным допуском на опоздание. Это не простой таймер от текущего времени компьютера. Для продвижения важны сведения, которые обработка действительно увидела.
Условный пример: самое позднее увиденное событие относится к 10:30, допуск составляет десять минут. Ориентир для границы находится около 10:20. Это объяснение идеи, а не обещание немедленного переключения ровно в указанную секунду: реальное продвижение согласуется между частями обработки. По часам на стене могло пройти намного больше времени.
Какая гарантия действует для опоздания
Для агрегирования с правильно заданной временной границей руководство Structured Streaming даёт одностороннюю гарантию: сведения, опоздавшие меньше допустимого порога относительно увиденного времени событий, не отбрасываются из-за этой границы. Для более старых сведений включение в расчёт уже не гарантируется.
Поэтому неверны два упрощения: «всё позднее точно потеряется» и «Spark обязательно примет любое событие». В учебном примере запись с временем 10:25 ещё находится в пределах описанного допуска относительно 10:30. С записью за 10:05 нельзя обещать тот же результат. Для реальной проверки нужны конкретная операция, режим выдачи и история поступления.
Зачем завершать прошлые интервалы
Чтобы дополнить итог за старый интервал, обработке приходится помнить промежуточные сведения. Они образуют состояние расчёта. Если сохранять всё бесконечно, объём такой памяти о прошлом может расти. Временная граница помогает определить, какие части состояния уже допустимо убрать при поддерживающих это операциях.
Документация Microsoft Fabric описывает компромисс: больший допуск сохраняет больше состояния, меньший может исключить корректные, но поздние сведения. Очистка тоже не обязана происходить мгновенно. Как сама работа делится между исполнителями, объясняем отдельно в статье о распределённой обработке Spark.
Почему граница иногда перестаёт двигаться
Если новые сведения не приходят, временная граница может не продвигаться. При нескольких входных потоках их совместный прогресс также имеет значение: по умолчанию более медленный источник способен задержать общую границу. Это помогает понять, почему итог ещё не завершён, хотя по обычным часам давно пора ждать результат.
В нашем условном сценарии нельзя решить проблему одной фразой «подождём ещё десять минут». Сначала стоит выяснить, какие времена событий увидены, работают ли все источники и что именно должно завершиться. Рост ресурсов при этом не всегда относится к одному механизму: например, память управляющей части Spark требует отдельного разбора.
Как выбрать допуск осмысленно
Предлагаемый порядок обсуждения: измерить реальные задержки источника, согласовать допустимую свежесть результата и решить, как исправлять сведения за пределами оперативного ожидания. Универсального числа минут для всех систем нет. Если бизнесу нужна последующая сверка с полной историей, такой путь следует предусмотреть отдельно: временная граница не создаёт его автоматически.
Изучать распределённые и потоковые вычисления можно на курсе PySpark для инженеров и аналитиков данных. Для начала полезно словами разобрать несколько событий с разным временем поступления. Цель — объяснить, какой итог они должны дополнить, что ещё помнит расчёт и где заканчивается обещание оперативной обработки.


