歡迎訪問我的GitHubhttps://github.com/zq2599/blog_demos 內容:所有原創(chuàng)文章分類匯總及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等; 歡迎訪問我的GitHub
Flink處理函數實戰(zhàn)系列鏈接本篇概覽
編碼實戰(zhàn)接下來咱們開發(fā)一個應用來體驗CoProcessFunction,功能非常簡單,描述如下:
源碼下載如果您不想寫代碼,整個系列的源碼可在GitHub下載到,地址和鏈接信息如下表所示(https://github.com/zq2599/blog_demos):
這個git項目中有多個文件夾,本章的應用在flinkstudy文件夾下,如下圖紅框所示: Map算子
package com.bolingcavalry.coprocessfunction; import org.apache.flink.api.common.functions.MapFunction; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.util.StringUtils; public class WordCountMap implements MapFunction<String, Tuple2<String, Integer>> { @Override public Tuple2<String, Integer> map(String s) throws Exception { if(StringUtils.isNullOrWhitespaceOnly(s)) { System.out.println("invalid line"); return null; } String[] array = s.split(","); if(null==array || array.length<2) { System.out.println("invalid line for array"); return null; } return new Tuple2<>(array[0], Integer.valueOf(array[1])); } } 便于擴展的抽象類
package com.bolingcavalry.coprocessfunction; import org.apache.flink.api.java.tuple.Tuple; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.streaming.api.datastream.KeyedStream; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.functions.co.CoProcessFunction; /** * @author will * @email zq2599@gmail.com * @date 2020-11-09 17:33 * @description 串起整個邏輯的執(zhí)行類,用于體驗CoProcessFunction */ public abstract class AbstractCoProcessFunctionExecutor { /** * 返回CoProcessFunction的實例,這個方法留給子類實現(xiàn) * @return */ protected abstract CoProcessFunction< Tuple2<String, Integer>, Tuple2<String, Integer>, Tuple2<String, Integer>> getCoProcessFunctionInstance(); /** * 監(jiān)聽根據指定的端口, * 得到的數據先通過map轉為Tuple2實例, * 給元素加入時間戳, * 再按f0字段分區(qū), * 將分區(qū)后的KeyedStream返回 * @param port * @return */ protected KeyedStream<Tuple2<String, Integer>, Tuple> buildStreamFromSocket(StreamExecutionEnvironment env, int port) { return env // 監(jiān)聽端口 .socketTextStream("localhost", port) // 得到的字符串"aaa,3"轉成Tuple2實例,f0="aaa",f1=3 .map(new WordCountMap()) // 將單詞作為key分區(qū) .keyBy(0); } /** * 如果子類有側輸出需要處理,請重寫此方法,會在主流程執(zhí)行完畢后被調用 */ protected void doSideOutput(SingleOutputStreamOperator<Tuple2<String, Integer>> mainDataStream) { } /** * 執(zhí)行業(yè)務的方法 * @throws Exception */ public void execute() throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 并行度1 env.setParallelism(1); // 監(jiān)聽9998端口的輸入 KeyedStream<Tuple2<String, Integer>, Tuple> stream1 = buildStreamFromSocket(env, 9998); // 監(jiān)聽9999端口的輸入 KeyedStream<Tuple2<String, Integer>, Tuple> stream2 = buildStreamFromSocket(env, 9999); SingleOutputStreamOperator<Tuple2<String, Integer>> mainDataStream = stream1 // 兩個流連接 .connect(stream2) // 執(zhí)行低階處理函數,具體處理邏輯在子類中實現(xiàn) .process(getCoProcessFunctionInstance()); // 將低階處理函數輸出的元素全部打印出來 mainDataStream.print(); // 側輸出相關邏輯,子類有側輸出需求時重寫此方法 doSideOutput(mainDataStream); // 執(zhí)行 env.execute("ProcessFunction demo : CoProcessFunction"); } }
子類決定CoProcessFunction的功能
package com.bolingcavalry.coprocessfunction; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.streaming.api.functions.co.CoProcessFunction; import org.apache.flink.util.Collector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CollectEveryOne extends AbstractCoProcessFunctionExecutor { private static final Logger logger = LoggerFactory.getLogger(CollectEveryOne.class); @Override protected CoProcessFunction<Tuple2<String, Integer>, Tuple2<String, Integer>, Tuple2<String, Integer>> getCoProcessFunctionInstance() { return new CoProcessFunction<Tuple2<String, Integer>, Tuple2<String, Integer>, Tuple2<String, Integer>>() { @Override public void processElement1(Tuple2<String, Integer> value, Context ctx, Collector<Tuple2<String, Integer>> out) { logger.info("處理1號流的元素:{},", value); out.collect(value); } @Override public void processElement2(Tuple2<String, Integer> value, Context ctx, Collector<Tuple2<String, Integer>> out) { logger.info("處理2號流的元素:{}", value); out.collect(value); } }; } public static void main(String[] args) throws Exception { new CollectEveryOne().execute(); } }
驗證
12:45:38,774 INFO CollectEveryOne - 處理1號流的元素:(aaa,111), (aaa,111) 12:45:43,816 INFO CollectEveryOne - 處理2號流的元素:(bbb,222) (bbb,222) 更多
|
|