繁体   English   中英

Flink 与 Kafka 并行度优化

[英]Flink and Kafka parallelism optimization

我在 Flink 中有一个项目需要优化。 我已将默认并行度和插槽设置为 4(服务器有 4 个内核)。

taskmanager.numberOfTaskSlots = 4
parallelism.default = 4

这是我运行任务的配置,但无论是否使用并行处理,处理时间都是一样的。 在我的测试中,处理来自具有 5 个分区的 Kafka 队列的 30MB 大约需要 3 分钟。

public void run() throws Exception {
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    env.setRestartStrategy(RestartStrategies.fallBackRestart());
    // Get the Accounts DataSource
    BroadcastStream<PropertyInfo> propertyInfoBroadcastStream = getBroadcastPropertyStream(env);

    // Get the DataSource
    DataStream<CollectionMessage> collectionMessageDataStream = getCollectionMessageStream(env);
    final var router = new KeyedProcessAccumulatorRouterImpl(config);
    final Duration sessionGapDuration = config.get(SESSION_EVENT_GAP_MINUTES);
    SessionKeyedProcessFunction sessionKeyedProcessFunction = new SessionKeyedProcessFunction(
            router, sessionGapDuration, config);

        collectionMessageDataStream
          .keyBy(CollectionMessage::getSessionId)
          .connect(propertyInfoBroadcastStream)
          .process(sessionKeyedProcessFunction)
          .uid("SessionWindow")
          .name("Session Window")
          .setParallelism(4);

    // execute program
    env.execute("Processor");
}

private DataStream<CollectionMessage> getCollectionMessageStream(
        StreamExecutionEnvironment env) {
    Properties properties = new Properties();
    properties.setProperty("bootstrap.servers", config.getString(KAFKA_CONSUMER_SERVERS));
    properties.setProperty("group.id", config.getString(KAFKA_TOPROCESS_TOPIC));
    properties.setProperty("max.partition.fetch.bytes",
        config.getString(KAFKA_TOPROCESS_MAX_BYTES));
    FlinkKafkaConsumer<RawCollection> myConsumer = new FlinkKafkaConsumer<>(
        config.getString(KAFKA_TOPROCESS_TOPIC), new KafkaMessageDeserializer(), properties);

    // Take lines from file from files
    DataStream<RawCollection> inputMessageStream =
        env.addSource(myConsumer).setParallelism(4);

    B64PayloadDeserializer b64PayloadDeserializer =
        new B64PayloadDeserializer(new BaseCollectionMessageDeserializer());

    // Map lines to messages
    DataStream<CollectionMessage> collectionMessageDataStream =
        inputMessageStream
            .map(b64PayloadDeserializer::deserialize).setParallelism(4)
            .uid("CollectionMessageFilter")
            .name("Filter Collection Messages").setParallelism(4);

    // Assign new watermark on messages based on event time
    return collectionMessageDataStream;
}

查看 Flink 仪表板,我看到 4 个槽,4 个子任务中的每一个都忙到接近 100%。 在本地执行它并在 class SessionKeyedProcessFunction 中停止我看到 4 个并行任务。 不优化性能会发生什么?

在此处输入图像描述

通常,这比仅仅增加并行度并期望显着加速要复杂一些。 需要检查的几件事可能会导致并行性带来的性能提升低于预期:

  1. Kafka 上的消息是如何分区的? 您有 5 个分区,但这些分区中实际有多少条消息? 也许一个分区非常热,导致所有工作都由一个操作员实例完成。
  2. sessionId是如何分配的? 也许那里存在偏差,导致一个运算符实例完成大部分工作。
  3. 你如何衡量这 3 分钟? 这 3 分钟中的哪一部分实际上是在完成工作,而不是初始化、等待和清理? 也许您用于测试的样本太小,无法实际显示加速,因为大部分时间都与不可并行化的工作有关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM