---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ytsaurus.tech/docs/en/flow/concepts/swift.md
  - https://ytsaurus.tech/docs/ru/flow/concepts/swift.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ytsaurus.tech/docs/ru/llms.txt

<!-- source: ru/_includes/flow/concepts/swift.md -->
# Swift в YTsaurus Flow

**Swift** — принцип обработки данных в YTsaurus Flow, при котором результат работы [компьютейшена](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#computation) **не сохраняется в YTsaurus**. Вместо этого функция преобразования должна быть строго детерминированной: если результат потребуется повторно (например, при перезапуске джоба), он будет вычислен заново из тех же входных данных.


## Зачем это нужно {#motivation}

В классическом подходе (`TTransformComputation`) каждая [эпоха](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#epoch) завершается транзакционной записью результатов в YTsaurus. Это обеспечивает exactly-once, но создаёт нагрузку на кластер: для каждого входного сообщения выполняется лукап и запись в таблицу дедупликации, плюс по одной записи на каждое выходное сообщение.

Swift снимает это ограничение: если функция детерминирована, хранить её вывод не нужно — при необходимости его можно воспроизвести. Это позволяет:

- снизить нагрузку на YTsaurus до нуля или до минимума (только метаданные),
- повысить пропускную способность при stateless-преобразованиях.

## Как сохраняются гарантии exactly-once {#exactly-once}

Несмотря на отсутствие записи выходных данных в YTsaurus, гарантии [exactly-once](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#exactly-once) сохраняются за счёт детерминированности:

- Если джоб упал до доставки результата, Flow перезапускает его и получает **тот же вывод** из тех же входных данных.
- [Message Distributor](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#message-distributor) продолжает доставлять сообщение до получения подтверждения (`MarkPersisted`) от получателя, что исключает потери.

Таким образом, exactly-once обеспечивается не хранением вывода, а **идемпотентностью** вычисления.

## Требование детерминированности {#determinism}

Функция преобразования в Swift-компьютейшене должна быть **детерминированной**: при одних и тех же входных данных должен возвращаться одинаковый вывод, включая порядок сообщений.

Требование распространяется и на [lineage](https://ytsaurus.tech/docs/ru/flow/concepts/lineage.md) — привязку выходных сообщений к родительским: при повторном вычислении каждый вывод должен получить тех же родителей в том же порядке. Типичная ошибка — итерация по неупорядоченной структуре (например, hash-таблице или множеству) при разбиении батча на группы: порядок групп меняется от запуска к запуску, и повторное вычисление даёт другой вывод. По умолчанию у каждого выходного сообщения Swift-компьютейшена ровно один родитель; несколько родителей допустимы только при [`allow_batching_with_relaxed_guarantees`](https://ytsaurus.tech/docs/ru/flow/concepts/guarantees.md#swift-allow-batching-with-relaxed-guarantees).

{% note warning %}

Нарушение детерминированности при обновлении пайплайна без [дрейна](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#start-stop-pause-pipeline) может привести к дубликатам или потере промежуточных сообщений: разные части системы могут обработать разные версии вывода.

{% endnote %}

Из этого правила могут быть исключения, обусловленные особенностями бизнес-логики пайплайна, но разработчик бизнес-логики должен точно представлять, почему он их реализует, и за счёт каких механизмов результат работы пайплайна в целом останется корректным.

По умолчанию Flow дописывает к message id производного сообщения его порядковый номер. Если два повтора Swift-вычисления порождают на одной позиции разные сообщения, они получают одинаковый message id. Это может привести к потере данных или появлению дубликатов, а если у сообщений различаются ключи — также к нарушению внутренних инвариантов Flow. В C++, Java, Python и Go через output options можно исключить порядок из идентичности сообщения, выбрав хеш payload или пользовательский суффикс (см. [описание C++ API](https://ytsaurus.tech/docs/ru/flow/cpp/process-functions.md#message-id-suffixes)). Это защищает от такого совпадения идентификаторов только при стабильном семантическом суффиксе и не делает недетерминированное вычисление детерминированным.


## Классы Swift-компьютейшенов {#classes}

В Flow реализовано два базовых Swift-класса:

### TSwiftMapComputation {#swift-map}

Детерминированный Map без материализации результатов в YTsaurus.

- **Нагрузка на YTsaurus:** ~0 записей за эпоху (только системные фоновые процессы).
- **Не поддерживает:** [Source](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#source), [Sink](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#sink).
- **Поддерживает:** [таймеры](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#timer) и [key-visitor-стримы](https://ytsaurus.tech/docs/ru/flow/concepts/key_visitor.md) — только для работы со [стейтом](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#state), например для фонового клинапа (GC). Эмит выходных сообщений из обработки таймера или визита **запрещён**: output-стрим не может зависеть от таймер- или visit-стрима в `streams_dependency`. Так как таймер-стримы по умолчанию добавляются в зависимости каждого output-а, спека с таймерами и output-ами обязана задавать `streams_dependency` явно.
- **Требует:** строгой детерминированности и того, чтобы у каждого результирующего сообщения был ровно один родитель — входное сообщение.

Подробнее — в разделе [Computation (C++)](https://ytsaurus.tech/docs/ru/flow/cpp/computation.md#tswiftmapcomputation).

### TSwiftPassthroughComputation {#swift-passthrough-map}

[Passthrough-компьютейшен](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#passthrough) — наследник `TSwiftMapComputation`. Конвертирует `input`-сообщения в схему `output`-стрима без пользовательской логики. Подробнее — [Computation (C++)](https://ytsaurus.tech/docs/ru/flow/cpp/computation.md#tswiftpassthroughcomputation).

### TSwiftOrderedSourceComputation {#swift-source}

Основной класс для чтения упорядоченных данных из внешних источников.

- **Нагрузка на YTsaurus:** ~1–2 записи за эпоху (метаданные для восстановления; сами сообщения не сохраняются).
- **Поддерживает:** `WatermarkStrategy` для оценки [вотермарков](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#timestamps-and-watermarks).
- **Требует:** ровно одного [Source](https://ytsaurus.tech/docs/ru/flow/concepts/glossary.md#source), реализующего `IOrderedSource`.

Подробнее — в разделе [Computation (C++)](https://ytsaurus.tech/docs/ru/flow/cpp/computation.md#tswiftorderedsourcecomputation).

### TSwiftPassthroughOrderedSourceComputation {#swift-passthrough-source}

Passthrough-компьютейшен — наследник `TSwiftOrderedSourceComputation`. Преобразует `source`-сообщения в `output`-стрим приведением к новой схеме. Подробнее — [Computation (C++)](https://ytsaurus.tech/docs/ru/flow/cpp/computation.md#tswiftpassthroughorderedsourcecomputation).

## Сравнение с TTransformComputation {#comparison}

| Тип | Запись в YTsaurus за эпоху | Поддержка таймеров | Поддержка стейта | Требование детерминированности |
|-----|-----------------------------------|--------------------|------------------|-------------------------------|
| `TTransformComputation` | 2 на каждое входное сообщение и 1 на выходное | Да | Да | Нет |
| `TSwiftOrderedSourceComputation` | ~1–2 (метаданные) | Нет | Нет | Да |
| `TSwiftPassthroughOrderedSourceComputation` | ~1–2 (метаданные) | Нет | Нет | Да |
| `TSwiftMapComputation` | ~0 | Да (только стейт) | Да | Да |
| `TSwiftPassthroughComputation` | ~0 | Нет | Нет | Да |

## См. также

- [Computation](https://ytsaurus.tech/docs/ru/flow/concepts/computation.md)
- [Гарантии обработки](https://ytsaurus.tech/docs/ru/flow/concepts/guarantees.md)
- [Computation (C++)](https://ytsaurus.tech/docs/ru/flow/cpp/computation.md)
- [Computation (Java)](https://ytsaurus.tech/docs/ru/flow/java/computation.md)
- [Computation (Python)](https://ytsaurus.tech/docs/ru/flow/python/computation.md)
- [Computation (Go)](https://ytsaurus.tech/docs/ru/flow/go/computation.md)
<!-- endsource: ru/_includes/flow/concepts/swift.md -->
