Несколько моментов для рассмотрения:
Установка параллелизма на 1 для всей работы предотвратит масштабирование вашего приложения, что повлияет на производительность. Вопрос о том, имеет ли это значение, зависит от требований вашего приложения, но это, безусловно, будет ограничением и может стать проблемой.
Если указанные вами агрегаты предназначены для глобального вычисления по всем записям событий, то для параллельной работы потребуется выполнить некоторую предварительную агрегацию параллельно. Но в этом случае вам придется уменьшить параллелизм до 1 на более поздних этапах графика работы, чтобы получить окончательные (глобальные) результаты.
Если, с другой стороны, эти агрегаты должны вычисляться независимо для каждого значения некоторого ключа, то имеет смысл рассмотреть возможность создания ключа потока и использовать это разделение в качестве основы для параллельной работы.
Все операции, о которых вы упоминаете, требуют определенного состояния, будь то вычисление максимума, минимума, среднего значения или времени безотказной работы. Например, вы не можете вычислить максимум, не помня максимум, который встречался до сих пор.
Если я правильно понимаю, как работает соединитель источника NiFi от Flink, то, если источник работает параллельно, нажатие клавиши приведет к потере событий.
Однако ни одна из упомянутых вами операций не требует, чтобы данные доставлялись по порядку. Вычисление времени безотказной работы (и времени простоя) для потока вне очереди потребует некоторой буферизации - эти операции должны будут ожидать поступления данных вне очереди, прежде чем они смогут дать результаты - но это, безусловно, выполнимо. Это именно то, что водяные знаки для; они определяют, как долго ждать неупорядоченных данных. Вы можете использовать таймер времени события в ProcessFunction, чтобы организовать обратный вызов onTimer, который будет вызван после обработки всех более ранних событий.
Вы всегда можете отсортировать поток с ключами. Вот пример .
Расчет времени работы / простоя должен легко выполняться с помощью библиотеки CEP Флинка (которая сортирует входные данные, кстати).
UPDATE:
Это правда, что после применения ProcessFunction к потоку с ключами поток больше не является ключом. Но в этом случае вы могли бы безопасно использовать reinterpretAsKeyedStream , чтобы сообщить Flink, что поток все еще имеет ключ.
Что касается CEP, эта библиотека использует состояние от вашего имени, что упрощает разработку приложений, которые должны реагировать на шаблоны.