Присоединитесь к stati c и динамическому c Kafka источнику во Flink - PullRequest
0 голосов
/ 19 марта 2020

Сегодня я хотел бы обратиться к концептуальной теме c о Флинке, а не к технической.

В нашем случае у нас есть две темы Кафки A и B, которые необходимо объединить , Объединение должно всегда включать все элементов из topi c A, а также все новые элементы из topi c B. Для этого есть 2 возможности: всегда создавать новый Потребитель и начать потребление topi c A с самого начала, или сохранить все элементы из topi c A в состоянии, когда они потреблены. В настоящее время технологический подход заключается в объединении двух DataStreams, что быстро показывает нам его ограничения для этого варианта использования, поскольку нет возможности объединить потоки без окна (достаточно справедливо). Элементы из topi c A в конечном итоге будут потеряны, если окно перейдет, и у меня появилось ощущение, что пользователь постоянно сбрасывает настройки, обойдя сложную логику c, представленную Flink.

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

Однако мой вопрос: прежде чем углубляться в API таблиц, хочу лишь заметить, что есть более элегантный способ, я хотел бы определить, является ли это оптимальным решением по этому вопросу или если есть даже лучше подходит концепция Flink, о которой я не знаю?

Редактировать: я забыл упомянуть: мы не используем POJO, а скорее оставляем его обобщенным c, что означает, что входящие данные идентифицируются как Tuple2<K,V>, где K,V каждый является экземпляром GenericRecord. Соответствующая схема для сериализации / десериализации получается из реестра схем во время выполнения. Я не знаю, в какой степени конструкции SQL могут стать узким местом в этой ситуации. Кроме того, это замечание из документации Both tables must have distinct field names заставляет меня немного сомневаться, поскольку у нас do есть те же имена полей, с которыми нам придется как-то обращаться, без огромных обходных путей.

1 Ответ

0 голосов
/ 19 марта 2020

Если A действительно статичен c, то будет дешевле, если вы каким-либо образом полностью загрузите A, либо в состояние Flink, либо в память, а затем направите поток B за A - получая результаты объединения без необходимости store B.

Есть хотя бы несколько способов сделать это с помощью Flink. Один из них описан в этого ответа , а другой связан с использованием State Processor API .

При втором подходе вы бы удерживали A в состоянии Flink с разделением по ключам. Используя API обработчика состояний, вы можете bootstrap сохранить точку, которая содержит желаемое состояние, так что при запуске задания с этой точки сохранения A уже полностью загружен и сразу доступен.

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

Другой альтернативой для реализации объединений без использования API таблицы является просто свернуть свой собственный с RichCoFlatMapFunction или KeyedCoProcessFunction. Вы найдете примеров этого в обучении Flink. Ни один из этих примеров не соответствует вашим требованиям, но они дают общее представление. Однако я не вижу в этом никакого преимущества - если вы собираетесь выполнить полностью динамическое / динамическое объединение c, то можете также использовать Table API.

...