算子
map
输入一个数据流,输出一个数据流
转换
1:1
flatmap
转换
1:n / n:1
filter
过滤
计算每个元素的布尔函数,并保留那些函数返回真的元素。
返回true通过
返回false排除
keyBy(x)
基于 key 对流进行分区。使用 hash 函数对流进行分区,返回 KeyedDataStream 数据流
以数组的第x个元素作为key来分组
通过keyBy,DataStream→KeyedStream。
reduce
reduce需要针对分组或者一个window(窗口)来执行,也就是分别对应于keyBy、window/timeWindow 处理后的数据,根据ReduceFunction将元素与上一个reduce后的结果合并,产出合并之后的结果
按分组来计算keyBy/timeWindow处理后的数据
Fold
将每个分组的最后一个文件流与当前记录组合来推出 KeyedStream。 然后返回数据流
min()
指定位置值最小,之覆盖之前的值不会把整个元素换成新的
min会根据指定的字段取最小值,并且把这个值保存在对应的位置上,对于其他的字段取了最先获取的值,不能保证每个元素的数值正确,max同理。
minBy()
返回指定字段取最小值的元素,并且会覆盖指定字段小于当前已找到的最小值元素。maxBy同理
max()、maxBy() 同min
sum()
指定位置求和
window()、windowAll
流处理 转换成 批处理,可以设置并行度, windowAll并行度始终为一
package aggregations;
import org.apache.flink.api.common.functions.FoldFunction;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.streaming.api.functions.windowing.WindowFunction;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class WindowTest {
private static final Logger LOG = LoggerFactory.getLogger(FoldTest.class);
private static final String[] TYPE = {"苹果", "梨", "西瓜", "葡萄", "火龙果"};
public static void main(String[] args) throws Exception {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//添加自定义数据源,每秒发出一笔订单信息{商品名称,商品数量}
DataStreamSource<Tuple2<String, Integer>> orderSource = env.addSource(new SourceFunction<Tuple2<String, Integer>>() {
private volatile boolean isRunning = true;
private final Random random = new Random();
@Override
public void run(SourceContext<Tuple2<String, Integer>> ctx) throws Exception {
while (isRunning) {
TimeUnit.SECONDS.sleep(1);
String type = TYPE[random.nextInt(TYPE.length)];
System.out.println("---------------");
System.out.println(type);
ctx.collect(Tuple2.of(type, 1));
// ctx.collect(Tuple2.of(TYPE[random.nextInt(TYPE.length)], 1));
}
}
@Override
public void cancel() {
isRunning = false;
}
}, "order-info");
//这里只为将DataStream → KeyedStream,用空字符串做分区键。所有数据为相同分区
orderSource
.keyBy(0).timeWindow(Time.seconds(5))
.apply(new MyTimeWindowFunction()).print();
env.execute("Flink Streaming Java API Skeleton");
}
}
class MyTimeWindowFunction implements WindowFunction<Tuple2<String,Integer>, String, Tuple, TimeWindow> {
@Override
public void apply(Tuple tuple, TimeWindow window, Iterable<Tuple2<String, Integer>> input, Collector<String> out) throws Exception {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
int sum = 0;
for(Tuple2<String,Integer> tuple2 : input){
sum +=tuple2.f1;
}
long start = window.getStart();
long end = window.getEnd();
out.collect(tuple.getField(0) + " " + sum + "\nwindow_start :"
+ format.format(start) + "\nwindow_end :" + format.format(end)
);
}
}
apply()
apply是窗口的应用函数,即apply里的函数将应用在此窗口的数据上
Split
一个流划成两个或多个
Select
从拆分流中选择指定的流
Project
从流中选择指定属性
Union
结合两个或多个流