flink java旁路输出(Side Output),对原始流进行分流、复制

flink通过ProcessFunction来分流,可以将一份流进行拆分、复制等操作,比如下面的代码通过读取一个基本的文本流,将流分别做处理后进行输出:

案例代码

package wordcount;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.ProcessFunction;
import org.apache.flink.util.Collector;
import org.apache.flink.util.OutputTag;


public class manyOutWordCount {

    public static void main(String[] args) throws Exception {
        // 1.创建流式执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        // 2.从文件中读取数据
        DataStream<String> dataStream = env.readTextFile("src/main/resources/hello.txt");
        // 执行环境并行度设置3
        env.setParallelism(3);
        // 3.按照空格分词,流的类型是new Tuple2<>(wordLine, 1)
        DataStream<Tuple2<String, Integer>> sensorStream = dataStream.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
            @Override
            public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
                String[] wordString = value.split(" ");
                for (String wordLine : wordString) {
                    out.collect(new Tuple2<>(wordLine, 1));
                }
            }
        });

        //旁路输出,拆分流
        final OutputTag<Tuple2<String, Integer>> sideStream = new OutputTag<Tuple2<String, Integer>>("te") {
        };
        SingleOutputStreamOperator<Tuple2<String, Integer>> mainDataStream = sensorStream.process(new ProcessFunction<Tuple2<String, Integer>, Tuple2<String, Integer>>() {
            @Override
            public void processElement(Tuple2<String, Integer> value, ProcessFunction<Tuple2<String, Integer>, Tuple2<String, Integer>>.Context ctx, Collector<Tuple2<String, Integer>> out) throws Exception {
                out.collect(new Tuple2<>(value.f0, 2)); // 这里把 mainDataStream 的输出变为 Tuple(单词,2)
                ctx.output(sideStream, value); // 这里把 sideStream 的输出变为 Tuple(单词,1)
            }
        });
        DataStream<Tuple2<String, Integer>> sideOutput = mainDataStream.getSideOutput(sideStream);//获取sideOutput的数据

        sideOutput.print();
        mainDataStream.print();

        //执行
        env.execute();
    }
}

其中数据hello.txt的文件内容是:

hello world
hello flink
hello spark
When we have shuffled off this mortal coil
When we have shuffled off this mortal coil
ack
hello world
hello flink
hello spark
When we have shuffled off this mortal coil
When we have shuffled off this mortal coil
ack
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要使用 Apache Flink 消费 Kafka 中的数据并对数据进行分流,您可以按照以下步骤进行操作: 1. 在 Flink 中添加 Kafka 依赖项。您可以在 pom.xml 文件中添加以下依赖项: ```xml <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java_${scala.binary.version}</artifactId> <version>${flink.version}</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-kafka_${scala.binary.version}</artifactId> <version>${flink.version}</version> </dependency> ``` 其中,`${scala.binary.version}` 是您正在使用的 Scala 版本,`${flink.version}` 是您正在使用的 Flink 版本。 2. 创建一个 Flink 程序,并在程序中添加以下代码,以消费 Kafka 中的数据: ```java import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; import java.util.Properties; public class KafkaConsumer { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); Properties properties = new Properties(); properties.setProperty("bootstrap.servers", "localhost:9092"); properties.setProperty("group.id", "test"); FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>("my-topic", new SimpleStringSchema(), properties); DataStream<String> stream = env.addSource(consumer); // 在这里对数据进行处理 // ... env.execute("KafkaConsumer"); } } ``` 在上述代码中,我们使用 `FlinkKafkaConsumer` 类从 Kafka 中消费数据,并使用 `SimpleStringSchema` 将数据转换为字符串类型的 `DataStream`。您需要根据您的实际需求更改参数和类型。 3. 对数据进行分流。在上述代码中,您可以在 `// 在这里对数据进行处理` 注释下方添加代码来对数据进行分流,例如: ```java import org.apache.flink.streaming.api.datastream.SplitStream; import org.apache.flink.streaming.api.functions.ProcessFunction; import org.apache.flink.util.Collector; public class KafkaConsumer { public static void main(String[] args) throws Exception { // ... DataStream<String> stream = env.addSource(consumer); SplitStream<String> splitStream = stream.split(new ProcessFunction<String, String>() { @Override public void processElement(String value, Context ctx, Collector<String> out) throws Exception { if (value.contains("A")) { out.collect("stream-a"); } else if (value.contains("B")) { out.collect("stream-b"); } else { out.collect("stream-c"); } } }); // 对分流后的数据进行处理 // ... env.execute("KafkaConsumer"); } } ``` 在上述代码中,我们使用 `split` 方法将数据分为三个:以 "A" 开头的数据、以 "B" 开头的数据和其余数据。您可以根据您的实际需求更改分流的逻辑。 4. 对分流后的数据进行处理。在上述代码中,您可以在 `// 对分流后的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆萌的代Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值