ウィンドウの流れ
WindowedStream 純粋なAPIの設定、ランタイムWindowedStreamにKeyedStreamのウィンドウや操作上のマージ操作。
集計
フィールドによって、または位置によって(タプル)重合対流/パケット
プライベートDEF集合体(aggregationType:AggregationType、フィールド:文字列):でDataStream [T] = { valの位置= fieldNames2Indices(getInputType()、アレイ(フィールド))(0) 総計(aggregationType、位置) } DEF凝集(aggregationType:AggregationType、位置:INT):でDataStream [T] = { ヴァルjStream = javaStream.asInstanceOf [JavaWStream [商品、K、W] ヴァル減速= aggregationType一致{ 場合AggregationType.SUM => 新しいSumAggregator(位置、jStream.getInputType、jStream。 getExecutionEnvironment.getConfig) 場合_ => 新しいComparableAggregator( 位置、 jStream.getInputType、 aggregationType、 真、 jStream.getExecutionEnvironment.getConfig) } 新しいでDataStream [製品](jStream.reduce(減速))。asInstanceOf〔でDataStream [T] }
集計関数抽象クラス
パブリック抽象クラスAggregationFunction <T>を実装ReduceFunction <T> { プライベート静的最終長いのserialVersionUID = 1L。 / ** ウィンドウストリームまたはキー付きストリームで使用することができます*集計タイプ。 * / パブリック列挙AggregationType { SUM、MIN、MAX、MINBY、MAXBY、 } }
抽象クラスを実装することはSumAggregator、ComparableAggregatorを持っています
例えばSumAggregatorは、ReduceFunctionは(抽象クラスAggregationFunction上継承を介して)インタフェースを実装します
パブリッククラスSumAggregator <T>に延びAggregationFunction <T> { プライベート静的最終長いのserialVersionUID = 1L。 民間最終FieldAccessor <T、オブジェクト> fieldAccessor。 民間最終SumFunctionの加算器と、 民間最終TypeSerializer <T>シリアライザ。 民間最終ブールisTuple。 公共SumAggregator(INT POS、種別情報<T> TYPEINFO、ExecutionConfig設定){ fieldAccessor = FieldAccessorFactory.getAccessor(TYPEINFO、POSは、config); 加算器= SumFunction.getForClass(fieldAccessor.getFieldType()getTypeClass()。)。 {(TYPEINFOのinstanceof TupleTypeInfo)場合 isTupleがtrue =。 シリアライザ= NULL; }他{ isTuple = FALSE; this.serializer = typeInfo.createSerializer(設定)。 } } パブリックSumAggregator(Stringフィールド、種別情報<T> TYPEINFO、ExecutionConfig設定){ fieldAccessor = FieldAccessorFactory.getAccessor(TYPEINFO、フィールドは、config); 加算器= SumFunction.getForClass(fieldAccessor.getFieldType()getTypeClass()。)。 {(TYPEINFOのinstanceof TupleTypeInfo)場合 isTupleがtrue =。 シリアライザ= NULL; }他{ isTuple = FALSE; this.serializer = typeInfo.createSerializer(設定)。 } } @Override @SuppressWarnings( "未チェック") 公衆T(T値1、値2 T)は例外{スロー減らす IF(isTuple){ タプル結果=((タプル)値1).copyを(); リターンfieldAccessor.set((T)の結果、adder.add(fieldAccessor.get(値1)、fieldAccessor.get(値2)))。 }他{ T結果= serializer.copy(値1)。 リターンfieldAccessor.set(その結果、adder.add(fieldAccessor.get(値1)、fieldAccessor.get(値2)))。 } } }
一般的な導出方法
和
DEF SUM(位置:INT):でDataStream [T] =集合体(AggregationType.SUM、位置)
maxBy
DEF maxBy(位置:INT):でDataStream [T] =集合体(AggregationType.MAXBY、位置)
例のコードスニペット
和
ヴァルカウント:でDataStream [(文字列、INT)] = text.flatMap(_ toLowerCaseメソッド()スプリット( "\\ W +")。) .filter(_空ではない。) .MAP((_、1)) .keyBy( 0) .countWindow(windowSize、slideSize) .SUM(1)
maxBy
ヴァルカウント:でDataStream [(文字列、INT)] = text.flatMap(_ toLowerCaseメソッド()スプリット( "\\ W +")。) .filter(_空ではない。) .MAP((_、1)) .keyBy( 0) .countWindow(windowSize、slideSize) .maxBy(1)
減らします
ハンドラはの重要な要素を設定するために同じですが別々に適用しました
でDataStream [T] = {:DEF((T、T)=> T機能)を低減 (機能== NULL)が{場合 新しいNullPointerExceptionがスロー( "nullであってはならない機能を削減") } ヴァルcleanFun =クリーン(関数) ヴァル減速=新しいScalaReduceFunction [T](cleanFun) 低減(減速) }
インターフェイスもReduceFunctionを実装します
最終的なクラスScalaReduceFunction [T](プライベート[これ]ヴァル関数:(T、T)=> T)は ReduceFunction [T] {延び @throws(classOf [例外]) オーバーライドDEF低減(:T、B:T): T = { 関数(A、B) } }
ソース・コール
//ファイル:org.apache.flink.streaming.api.datastream.WindowedStream 公共<R> SingleOutputStreamOperator <R>減らす( ReduceFunction <T> reduceFunction、 窓関数<T、R、K、W>関数、 種別情報<R> resultTypeと){ IF(reduceFunction instanceofのRichFunction){ 新しいUnsupportedOperationExceptionが(スロー) "RichFunctionことができない減らすのReduceFunction。"; } //クロージャがきれい 。; = input.getExecutionEnvironment()クリーン(機能)機能 。reduceFunction = input.getExecutionEnvironment()クリーン(reduceFunction)。 最終列OPNAME = generateOperatorName(windowAssigner、トリガー、エビクタ、reduceFunction、機能)。 KeySelector <T、K> keySel =入力。 OneInputStreamOperator <T、R>オペレータ; IF(エビクタ!= NULL){ @SuppressWarnings({ "未チェック"、 "rawtypes"}) TypeSerializer <StreamRecord <T >> streamRecordSerializer = (TypeSerializer <StreamRecord <T >>)新しいStreamElementSerializer(input.getType()。createSerializer( getExecutionEnvironment()GETCONFIG()))。 ListStateDescriptor <StreamRecord <T >> stateDesc = 新しいListStateDescriptor <>( "ウィンドウの内容"、streamRecordSerializer)。 演算子= 新しいEvictingWindowOperator <>(windowAssigner、 windowAssigner.getWindowSerializer(getExecutionEnvironment()。GETCONFIG())、 keySel、 input.getKeyType()。 新しいInternalIterableWindowFunction <>(新しいReduceApplyWindowFunction <>(reduceFunction、関数))、 トリガー、 エビクタ、 allowedLateness、 lateDataOutputTag)。 }他{ ReducingStateDescriptor <T> stateDesc =新しいReducingStateDescriptor <>( "ウィンドウの内容"、 reduceFunction、 input.getType()createSerializer(getExecutionEnvironment()GETCONFIG())); 演算子= 新しいWindowOperator <>(windowAssigner、 windowAssigner.getWindowSerializer(getExecutionEnvironment()。GETCONFIG())、 keySel、 input.getKeyType()。createSerializer(getExecutionEnvironment()。GETCONFIG())、 stateDesc、 新しいInternalSingleValueWindowFunction <>(機能)、 トリガー、 allowedLateness、 lateDataOutputTag)。 } 戻りinput.transform(OPNAME、resultTypeと、オペレータ)。 }
例のコードスニペット
stream.keyBy(0) .timeWindow(Time.of(2500 TimeUnit.MILLISECONDS)、Time.of(500、TimeUnit.MILLISECONDS)) .reduce((値1、値2)=>(value1._1、value1._2 + value2._2)) .addSink(新しいSinkFunction [(長い長いです)] {})
処理する
233
適用します
233