我在编写从sink子任务到输出kafka主题的键控流时遇到了问题。
作业的形式为:source->filter->keyby(id)->flatmap->sink
异常来自kafka生产者并导致检查点超时:
FlinkKafkaException: Failed to send data to Kafka: Failed to allocate memory within the configured max blocking time FlinkKafkaException: Failed to send data to Kafka: Expiring 16 record(s) for mytopic-11:120000 ms has passed since batch creation
在出现上述异常的情况下,作业会进入一个crashloop状态,偶尔会在再次发生crashloop之前暂时恢复。我认为这里的问题是,我使用键来确定输出分区,这会导致p sink子任务向每个扇出写入n个输出分区。理想情况下,每个子任务只能写入单个分区。
作业具有以下约束/属性:
1:一旦一个密钥被写入了一个输出Kafka主题分区,以后就需要一直写入同一个Kafka分区
2:接收器子任务并行度最初将等于输出分区的数量
3:以后我应该可以在不违反#1的情况下增加并行度
4:我永远不会向输出kafka主题添加新分区
如果 parallelism == partitions
,那么我相信flinkfixedpartitioner将是一个很好的解决方案。但是,我不认为如果我以后增加并行性,它会尊重原始的key->分区Map,因为它使用这个方案选择输出分区。
有没有一种技术可以用来满足这些约束条件?可能是对kafka生产者设置的一个调整,分割键控流的另一种方法,或者其他什么?
1条答案
按热度按时间pcww981p1#
您假设flink使用的分区逻辑与kafka使用的分区逻辑相同。如果给定4个键a、b、c和d,flink将a和b发送到一个sink示例,而c和d将发送到另一个sink示例,这是完全有可能的(我怀疑是这样)。Kafka可能使用了不同的分区逻辑,将a和c发送到一个分区,而b和d则写入另一个分区。
flink似乎不想公开给定密钥的密钥组,但是如果接收器的并行度与kafka分区的数量相同,那么您应该能够在自定义kafka分区逻辑中使用接收器示例的任务id。这有点野蛮,但它应该做你想做的事。
当我想得更多的时候,你也可以为flink编写一个自定义分区器,它使用与你的kafka主题的自定义分区器相同的逻辑。这将处理扩展到更多Flume示例的问题。