Поток покупок меняет итог по магазину. Разбираем три режима вывода Structured Streaming и объясняем, почему получатель должен понимать, что означает очередная строка.
Новая строка не всегда означает новую покупку
Представим условный экран продаж. Заказы поступают непрерывно, а сотрудник видит общий счётчик для каждого магазина. Через минуту тот же магазин появляется в очередной выдаче расчёта. Это ещё одна покупка, новый общий итог или повторное сообщение? Без договорённости о значении результата легко посчитать одно и то же несколько раз.
Structured Streaming — механизм потоковой обработки Apache Spark. Он пересчитывает результат по мере поступления сведений. Режим вывода определяет, какие строки результата передаются получателю на очередном шаге. Здесь важно отличать исходные события от рассчитанной таблицы: десять покупок могут превратиться в один итог по магазину.
Три варианта передачи результата
В описании режимов PySpark выделены три варианта. Append передаёт новые строки результата. Update передаёт изменившиеся строки, включая вновь появившиеся. Complete передаёт весь текущий результат. Английские названия пригодятся при обсуждении документации, но их смысл можно запомнить как добавление, изменения и полную выдачу.
При добавлении уже переданная строка не должна позднее меняться в рамках выбранного расчёта. Полная выдача включает и те строки, которые с предыдущего шага остались прежними. Режим изменений позволяет не отправлять неизменившиеся группы. Это описание содержания выдачи, а не обещание, что внешний экран или база сами правильно применят полученные сведения.
Условный пример с двумя магазинами
Допустим, на первом шаге итог первого магазина равен двум заказам, второго — одному. Затем первому приходит ещё один заказ. Его новый итог — три, у второго по-прежнему один. В режиме изменений получатель увидит обновлённый итог первого магазина. В полной выдаче он получит оба текущих итога, хотя второй не изменился.
Если получатель сложит прежние два заказа с новым итогом три, получится пять вместо трёх. Ошибка возникает в толковании сообщения, а не обязательно в самом расчёте. Для этого учебного примера предложим заранее подписать на схеме: передаётся общий итог группы или отдельное событие. Такая подпись помогает заметить неверное ожидание ещё до настройки инструмента.
Почему добавление подходит не каждому итогу
В руководстве Spark приведены ограничения сочетаний операций и режимов. Если агрегат, то есть сводный итог, ещё меняется, его нельзя сразу выдавать как окончательную строку добавления. Для подходящего расчёта по временным интервалам выдачу можно отложить до завершения интервала с учётом временной границы потока.
Условному магазину это задаёт выбор: видеть промежуточное значение, которое будет уточняться, или ждать завершённый интервал. Это разные требования к экрану. Нельзя одновременно обещать окончательность и немедленное включение любых будущих опозданий. Правило для запоздавших исправлений нужно обсуждать отдельно, исходя из того, какие решения принимают по отчёту.
Проверить нужно и сторону получателя
Поддерживаемый режим зависит также от способа записи. Например, штатная запись Spark в файловый каталог поддерживает режим добавления; нельзя считать любой файловый приёмник готовым обновлять ранее выданные группы. Проверять нужно всю связку: вид расчёта, режим, средство передачи и дальнейшую обработку результата.
Предлагаемый разбор перед запуском: взять одну группу, показать её прежний и новый итог, затем описать ожидаемое действие получателя словами. После этого добавить вторую, неизменившуюся группу. Небольшой пример выявляет разницу между заменой значения и добавлением нового события без большого набора тестовых сведений.
Как связать это с устройством Spark
Режим вывода не отвечает на вопрос, как Spark распределяет вычисления. А выбранный формат Parquet сам по себе не определяет смысл повторного итога. Это отдельные решения, которые важно связать в одном описании задачи.
Разобраться в обработке и передаче результатов можно на курсе PySpark для инженеров и аналитиков данных. Начните с понятного вопроса: что именно должен сделать следующий участник системы, когда снова увидит ту же группу?


