Я написал приложение, которое считывает 100 000 записей Avro в секунду из темы Kafka, выполняет агрегирование по ключу, использует переворачивающиеся окна с 5 различными размерами, выполняет некоторые вычисления, чтобы узнать наибольшее, наименьшее, начальное и конечное значение, и записывает обратно в другую тему Kafka.
Это приложение уже существует во Flink, но источником является RSocket в формате CSV, а приемником — Cassandra. Проблема в том, что новое приложение использует гораздо больше процессора и памяти. Я проверил эту статью и заметил, что производительность не упоминается.
Правильно ли я предполагаю, что разница в основном связана с сериализацией/десериализацией Avro, или Flink должен быть быстрее для этого варианта использования? Если разница невелика, я бы предпочел Kafka Streams, чтобы избежать необходимости управлять кластером.
Без тестов на вашем собственном оборудовании или JVM, профилирующей ваш код, трудно сказать, что будет быстрее.
Судя по тому, что я видел, Flink вызывает больше вызовов функций JVM, чем Kafka Streams.
Kafka Streams плохо работает (или вообще не работает) с внешними системами, такими как RSocket или Cassandra. Поэтому вам все равно понадобится Flink или какой-либо другой инструмент ETL, такой как Kafka Connect (т. е. управление кластером), чтобы получать данные в тему Kafka для последующей обработки, независимо от фреймворка.
Формат сериализации не должен иметь значения. Flink или Kafka Streams будут использовать точно такие же методы JVM из Avro (или любого другого формата) SDK.
Источником и стоком в конце концов будет Кафка. Я просто хочу знать, должен ли Flink быть более эффективным с точки зрения ресурсов при выполнении такого рода потоковой обработки с отслеживанием состояния (агрегация и работа с окнами)
Как я уже сказал, это будет для вас эталоном. Но, судя по моему опыту работы со стеками вызовов Flink и сетевыми издержками, нет.
Я не думаю, что на этот вопрос можно ответить в общем. И Flink, и Kafka Streaming можно настроить в соответствии с рабочей нагрузкой, а небольшие изменения параметров могут существенно повлиять на производительность. Как правило, нет фундаментальной причины, по которой Flink должен быть намного быстрее для такого варианта использования, чем Kafka Streams. Единственным исключением может быть перераспределение, которое всегда должно проходить через кластер Kafka для потоков Kafka и может оставаться внутри кластера для Flink, но, насколько я понимаю, в вашем случае использования вы не перераспределяете.
Однако формат сериализации может играть большую роль. Некоторые тесты, которые я помню для protobuf (аналогично для avro), показали, что размер в (Java) памяти в 100 раз больше, чем сериализованные данные по проводу. Опять же, это зависит от многих вещей, в частности от того, насколько вложенной/сложной является ваша схема. Если avro десериализовать в сложную объектную модель, это вызовет значительные накладные расходы ЦП/памяти по сравнению с передачей строк.
Однако единственный способ точно определить, что замедляет ваш вариант использования, — это профилировать его и посмотреть, на что тратятся дополнительные ресурсы.
Источник для «данные в 100 раз больше»? Вы сравниваете собственные сериализуемые объекты Java с другими?
Это почти один из тех вопросов «что лучше, x или y», которые SO не разрешает. Я бы добавил более подробную информацию о вашей настройке Flink с конкретным вопросом, например, «как я могу уменьшить требования к памяти и ЦП, чтобы быть ближе к (что вы считаете разумным).