Гарантия exactly-once
По умолчанию стриминг в SPYT даёт гарантию at-least-once — запись в выходную таблицу и фиксация смещения консьюмера выполняются независимо, поэтому при повторной обработке микробатча после сбоя в таблице могут появиться дубликаты.
Если дубликаты недопустимы, в SPYT есть два способа обеспечить exactly-once:
|
Подход |
Принцип работы |
Когда использовать |
|
Транзакционный режим (SPYT 2.10+) |
|
Когда важна корректность данных: финансовая аналитика, ML-признаки, инкрементальное построение витрин |
|
|
Когда нежелательна дополнительная нагрузка на RPC-прокси от транзакционного режима, или при поддержке старого кода |
Важно
Оба подхода гарантируют exactly-once только в рамках Spark-джобов в YTsaurus: гарантия покрывает запись в выходную таблицу и фиксацию смещения консьюмера. На внешние системы — запись в стороннюю БД, отправку сообщений в другие очереди, вызовы внешних API — гарантия не распространяется. Для таких сценариев нужны дополнительные меры на уровне приложения.
Если дубликаты в выходных данных допустимы, дополнительных настроек не требуется — нетранзакционный стриминг работает по умолчанию.
Производительность
Ниже — результаты замеров пропускной способности транзакционного режима относительно других подходов: нетранзакционного стриминга и идемпотентного приёмника.
Условия: синтетические нагрузки NEXMark-стиля, очередь 5 млн строк (16 таблетов, средний размер строки ~70 байт), 8 экзекьюторов × 2 ядра, коммунальный RPC-прокси в обоих режимах для честного сравнения.
|
Тип нагрузки |
Режим |
Пропускная способность |
|
Стрим-статик |
Нетранзакционный стриминг |
~22 700 строк/с |
|
Транзакционный стриминг |
~26 200 строк/с (+13%) |
|
|
Stateful-агрегация в 1-минутных событийных окнах |
Нетранзакционный стриминг |
~13 900 строк/с |
|
Транзакционный стриминг |
~14 000 строк/с (в пределах шума) |
|
|
Сравнение с идемпотентным приёмником (passthrough 1 млн строк, 1 экзекьютор × 1 ядро) |
Идемпотентный приёмник (сортированная таблица) |
~2 000 строк/с |
|
Транзакционный стриминг |
~2 600 строк/с (+23%) |
Транзакционный режим выигрывает там, где много мелких записей или есть shuffle (join, groupBy, агрегации): одна транзакция вместо нескольких десятков сокращает накладные расходы на коммиты. На stateful с малым объёмом выхода амортизировать нечего, поэтому разницы практически нет.
По сравнению с идемпотентным приёмником (который требует создания сортированной таблицы), транзакционный режим стабильно быстрее: запись идёт в упорядоченную таблицу, без поддержания сортированного индекса.
См. также
- Транзакционный режим — инструкция по включению
- Идемпотентный приёмник — альтернатива для stateless 1:1 трансформаций
- Structured Streaming — обзор и основные сценарии
- Опции стриминга — справочник опций