창 흐름
WindowedStream 순수 API 구성, 런타임 WindowedStream 받는 KeyedStream의 창 및 운영에 병합 작업을.
골재
필드 또는 위치 (튜플) 중합 대류 / 패킷에 의해
개인 DEF 집합체 (aggregationType : AggregationType 필드 : 문자열) 데이터 스트림 [T] = { 발 위치 = fieldNames2Indices (getInputType () 배열 (필드)) (0) 골재 (aggregationType 위치) } DEF 집합체 (aggregationType : AggregationType, 위치 : INT) : 데이터 스트림 [T] = { 브로 jStream = javaStream.asInstanceOf [JavaWStream [제품, K,] W] 브로 감속기 aggregationType 매치 = { 경우 AggregationType.SUM => 새로운 SumAggregator (위치 jStream.getInputType, jStream. getExecutionEnvironment.getConfig) 경우 _ => 새로운 ComparableAggregator ( 위치 jStream.getInputType, aggregationType, 진정한 jStream.getExecutionEnvironment.getConfig) } 새로운 데이터 스트림 [제품] (jStream.reduce (감속기)). asInstanceOf [데이터 스트림 [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 볼때, TypeInformation <T> TYPEINFO, ExecutionConfig 구성) { fieldAccessor = FieldAccessorFactory.getAccessor (TYPEINFO, POS, 구성); 가산기 = SumFunction.getForClass (fieldAccessor.getFieldType () getTypeClass ().); (TupleTypeInfo instanceof를 TYPEINFO)는 {만약 isTuple 해당 =; 직렬 = NULL; } 다른 { isTuple 거짓 =; this.serializer = typeInfo.createSerializer (구성); 경우 (isTuple) { } } 공개 SumAggregator (문자열 필드 TypeInformation <T> TYPEINFO, ExecutionConfig 구성) { fieldAccessor = FieldAccessorFactory.getAccessor (TYPEINFO, 필드 구성); 가산기 = SumFunction.getForClass (fieldAccessor.getFieldType () getTypeClass ().); (TupleTypeInfo instanceof를 TYPEINFO)는 {만약 isTuple 해당 =; 직렬 = NULL; } 다른 { isTuple 거짓 =; this.serializer = typeInfo.createSerializer (구성); } } @Override의 @SuppressWarnings ( "체크") 공중 감소 T (T 값 1, T 값 2) {예외 발생 튜플 결과 = ((튜플) VALUE1) .copy (); 창 fieldAccessor.set ((T) 결과 adder.add (fieldAccessor.get (값) fieldAccessor.get (값 2))); 사용한다} else { T 결과 serializer.copy = (값); 창 fieldAccessor.set (결과 adder.add (fieldAccessor.get (값) fieldAccessor.get (값 2))); } } }
일반적인 유도 방법
합집합
DEF (: 지능 총수) : 요약 데이터 스트림 [T] = 골재 (AggregationType.SUM 위치)
maxBy
DEF maxBy (총수 : INT) : 데이터 스트림 [T] = 골재 (AggregationType.MAXBY 위치)
예제 코드
합집합
발 카운트 : 데이터 스트림 [(문자열 INT) = text.flatMap (_와 toLowerCase () 스플릿 ( "\\ W +")..) .filter (_ 비어 있지.) .MAP ((_, 1)) .keyBy ( 0) .countWindow (windowSize, slideSize) .sum (1)
maxBy
발 카운트 : 데이터 스트림 [(문자열 INT) = text.flatMap (_와 toLowerCase () 스플릿 ( "\\ W +")..) .filter (_ 비어 있지.) .MAP ((_, 1)) .keyBy ( 0) .countWindow (windowSize, slideSize) .maxBy (1)
줄이다
처리기의 핵심 요소 세트에 대해 동일 별도로인가
데이터 스트림 [T] = {DEF ((T, T) => T) 함수 감소 (함수 == NULL의) {경우 새로운 NullPointerException이 던져 ( ". 널 안됩니다 함수를 줄이기 ') } 브로 cleanFun = 클린 (함수 ) 브로 감속기 새로운 ScalaReduceFunction = [T (cleanFun) 감소 (감속) }
를 구현 ReduceFunction 인터페이스]
최종 클래스 ScalaReduceFunction [T] (개인 [이] 브로 함수 (T, T) => T)가 ReduceFunction [T] {연장 @throws (classOf [예외]) 오버라이드 DEF 감소 (a : T, B : T) : T = { 함수 (a, b) } }
소스 호출
// 파일 : org.apache.flink.streaming.api.datastream.WindowedStream의 공개 <R> SingleOutputStreamOperator는 <R은> 감소 ( ReduceFunction <T> reduceFunction, WindowFunction <T, R, K, W> 함수 TypeInformation <R> resultType ) { 경우 (reduceFunction instanceof를 RichFunction) { 새로운 UnsupportedOperationException가을 (던져) "는 RichFunction 수 없습니다 감소의 ReduceFunction."; } 클로저 청소 // 작동 input.getExecutionEnvironment = () 깨끗한 (작용).; reduceFunction input.getExecutionEnvironment = () 깨끗한 (reduceFunction 참조).; 최종 문자열 opname을 generateOperatorName = (windowAssigner, 트리거 축출, reduceFunction 함수); KeySelector에 <T, K> keySel = 입력. OneInputStreamOperator <T, R> 연산자; 경우 (축출! = 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); 사용한다} else { 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, 값) => (value1._1, value1._2 + value2._2)) .addSink (새 SinkFunction [(긴 롱) {})
방법
(233)
대다
(233)