示例1. WordCount
public class WordCount {
public static void main(String[] args) throws Exception {
// 创建flink运行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//调用Source生成DataStream
DataStreamSource<String> line = env.socketTextStream("linux01", 1993);
//调用transformation
SingleOutputStreamOperator<Tuple2<String, Integer>> wordAndOne = line.flatMap(new LineSplitor());
KeyedStream<Tuple2<String, Integer>, Tuple> keyed = wordAndOne.keyBy(0);
SingleOutputStreamOperator<Tuple2<String, Integer>> result = keyed.sum(1);
//调用SinK
result.print();
//启动
env.execute("WordCount");
}
//使用内部静态类传参数
private static class LineSplitor extends RichFlatMapFunction<String,Tuple2<String,Integer>>{
@Override
public void flatMap(String line, Collector<Tuple2<String, Integer>> collector) throws Exception {
String[] words = line.split(" ");
for (String word : words) {
collector.collect(Tuple2.of(word,1));
}
}
}
}
示例2.MapFuntion和RichMapFunction的使用
/**
*使用MapFunction和RichMapFunction
* MapFunction 接口 重写map方法 实现运算逻辑
* RichMapFunction 抽象类 重写map方法 实现运算逻辑 还有更多的方法
* 例如 open方法 初始化时执行一次可以用来初始化数据库的连接
* close方法 停止job是执行一次,可以用来关闭数据库的连接
* getRuntimeContext方法 获取当前运行的上下文对象 获取一些信息
*/
public class MapFunctionDemo {
public static void main(String[] args) throws Exception {
//创建flink运行的环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//调用Source生成DataStream
DataStreamSource<String> line = env.socketTextStream("linux01", 7777);
//调用transformation
//SingleOutputStreamOperator<String> upper = line.map(new MyMapFunction());
SingleOutputStreamOperator<String> upper = line.map(new MyRichFunction());
//调用Sink
upper.print();
//启动
env.execute("MapFunctionDemo");
}
private static class MyRichFunction extends RichMapFunction<String,String>{
@Override
//初始化时执行一次 可以用来初始化数据库的连接
public void open(Configuration parameters) throws Exception {
//获取当前这个subtask的编号
int indexOfThisSubtask = getRuntimeContext().getIndexOfThisSubtask();
System.out.println("open 方法被执行了->"+indexOfThisSubtask);
}
@Override
//每条消息执行一次 可以用来使用连接关联数据
public String map(String value) throws Exception {
//获取当前这个subtask的编号
int indexOfThisSubtask = getRuntimeContext().getIndexOfThisSubtask();
System.out.println("map方法被执行了->"+indexOfThisSubtask);
return value.toUpperCase();
}
@Override
//停止Job时执行一次 可以用来关闭连接
public void close() throws Exception {
//获取当前这个subtask的编号
int indexOfThisSubtask = getRuntimeContext().getIndexOfThisSubtask();
System.out.println("close方法被执行了->"+indexOfThisSubtask);
}
}
private static class MyMapFunction implements MapFunction<String,String>{
@Override
public String map(String value) throws Exception {
return value.toUpperCase();
}
}
}
示例3.并行度
/**
* 理解程序的并行的相关的概念
*
* flink使用资源槽对内存进行隔离,一个TaskManager可以有多个TaskSlot
* 以后提交的job的并行度要小于等于集群可用的槽的数量
*
* 如果在集群中提交任务,必须提前指定并行度,比如使用命令提交需要只有-p参数指定
*
* 但是只本地local模式运行,就不要指定了(因为有默认并行度)
*/
public class ParallelismDemo {
public static void main(String[] args) throws Exception {
//创建flink运行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//指定运行环境的并行度
//env.setParallelism(12);
//获取当前运行环境的并行度
//在本地执行,运行环境的默认并行度为:当前机器CPU的逻辑核数(cpu线程数)
int parallelism = env.getParallelism();
System.out.println("当前运行环境的并行度->"+parallelism);
//调用Source创建DataStream
DataStreamSource<String> line = env.socketTextStream("linux01", 7777);
//查看socketSource的并行度
//SocketSource即调用socketTextStream创建的DataStream的并行度永远为1
int parallelism1 = line.getParallelism();
System.out.println("SocketSource创建的DataStream的并行度->"+parallelism1);
//map是多并行的算子,如果任务没有指定该算子的并行度,默认与执行环境的并行度一致
SingleOutputStreamOperator<String> upperStream = line.map(new MapFunction<String, String>() {
@Override
public String map(String value) throws Exception {
return value.toUpperCase();
}
});
int parallelism2 = upperStream.getParallelism();
System.out.println("map算子所在Task的并行度->"+parallelism2);
//print sink也是多并行的算子,如果任务没有指定该算子的并行度,默认与执行环境的并行度一
DataStreamSink<String> streamSink = upperStream.print();
int parallelism3 = streamSink.getTransformation().getParallelism();
System.out.println("Sink算子所在Task的并行度->"+parallelism3);
//启动
env.execute();
}
}
示例4.自己实现print算子的简单功能
/**
* 自己实现print算子的简单功能
*/
public class MyPrintSink {
public static void main(String[] args) throws Exception {
//创建flink运行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//调用Source生成DataStream
DataStreamSource<String> line = env.socketTextStream("linux01", 7777);
//调用transformation
SingleOutputStreamOperator<String> upperStream = line.map(new MapFunction<String, String>() {
@Override
public String map(String value) throws Exception {
return value.toUpperCase();
}
});
//调用自己定义的print
upperStream.addSink(new MyPrint());
//启动
env.execute("MyPrintSink");
}
//写一个自己定义的print算子
private static class MyPrint extends RichSinkFunction<String>{
@Override
//该方法每条数据执行一次
public void invoke(String value, Context context) throws Exception {
//获取正在运行的上下文对象
RuntimeContext runtimeContext = getRuntimeContext();
//获取这个subtask的编号
int indexOfThisSubtask = runtimeContext.getIndexOfThisSubtask();
System.out.println(indexOfThisSubtask+1+" > "+value);
}
}
}