Apache Flink — как остановить и возобновить потоковую обработку при последующем сбое

#apache-flink #flink-streaming

Вопрос:

У меня есть приложение Flink, которое использует входящие сообщения по теме Кафки с несколькими разделами, выполняет некоторую обработку, а затем отправляет их в приемник, который отправляет их по HTTP во внешнюю службу. Иногда нижестоящая служба находится ниже по потоку, обработка должна быть остановлена до тех пор, пока она не вернется в действие.

Я рассматриваю два подхода.

  1. Создайте исключение, если приемнику Http не удается отправить выходное сообщение. Это приведет к перезапуску задачи и задания в соответствии с настроенной стратегией перезапуска. В конце концов, нисходящая служба вернется, и система продолжит работу с того места, на котором она остановилась.
  2. Пусть приемник спит и повторит попытку при сбое; он может делать это постоянно, пока не вернется служба нижестоящего уровня.

Из того, что я понимаю, и из моего PoC, с 1. Я точно проиграю-хотя бы один раз гарантирую, так как сама раковина находится во внешнем состоянии. Насколько я вижу, вы не можете сделать простую транзакционную конечную точку HTTP, как это необходимо для реализации функции Twophasecommitsink.

С 2. это меньшая проблема, поскольку конвейер не будет работать до тех пор, пока приемник не выполнит успешную запись, и я могу полагаться на обратное давление во всей системе, чтобы приостановить извлечение сообщений из источника Кафки.

Основные вопросы, которые у меня есть, это:

  1. Правильно ли предположение, что вы не можете создать функцию twophasecommitsink для простой конечной точки HTTP?
  2. Какая из двух стратегий или ни одна из них не имеет наибольшего смысла?
  3. Мне не хватает более простых очевидных решений?

Ответ №1:

Я думаю, вы можете попробовать AsyncIO в Flink — https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/operators/asyncio/.

Попробуйте заставить конечную точку HTTP отправить ответ после того, как все операции с запросом будут выполнены, например, на http-сервере, процесс выполнения запроса будет выполнен, а результат будет передан в БД. Затем используйте асинхронный клиент http в операторе AsyncIO. Оператор AsyncIO будет ждать, пока оператор не получит ответ. Если произошла какая-либо ошибка, потоковый конвейер Flink выйдет из строя и перезапустит конвейер на основе стратегии восстановления.

Все запросы к конечной точке HTTP без получения ответа будут находиться во внутреннем буфере оператора AsyncIO, и после сбоя конвейера потоковой передачи запросы, ожидающие в буфере, будут сохранены в состоянии контрольной точки. Это также вызовет обратное давление, когда внутренний буфер заполнится.

Комментарии:

1. Я был привязан к идее сделать это с помощью раковины, но это кажется хорошим способом, спасибо

2. Приняли этот ответ. Единственной приемлемой альтернативой, которую я нашел, было управление очередью HTTP-запросов с использованием внутреннего состояния приемника, отправка их с пулом потоков с течением времени, но оператор асинхронности кажется эквивалентным, но готовым.

3. Это асинхронный оператор для 🙂