1.将处理结果落地到指定文件中
我们在实际大数据处理中,一般不会选择将结果落地到某个文件中,但是呢,基本所有的结果其实又都是落地在文件中的。比如mysql底层存储不也是一个.data文件么~
/**
* 1.将flink处理后的数据输出到指定文件
* 按照id聚合,统计pv
*/
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> textStream = env.readTextFile("D:\\develop\\projects\\flink-study-project\\src\\resources\\readfile");
DataStream<VisitorLog> logs = textStream.map(new MapFunction<String, VisitorLog>() {
@Override
public VisitorLog map(String value) throws Exception {
String[] strings = value.split(",");
return new VisitorLog(strings[0], strings[1], Long.parseLong(strings[2]));
}
});
//将简单转化之后的数据写到一个文件中
//两种写法相似,底层都会转化为sinkFunction。
// addsink的方式是以并行度命名part来执行 write的方式简单实现的写文件:wirte的源码底层也推荐使用addsink
deleteFile(new File("D:\\develop\\projects\\flink-study-project\\src\\resources\\simplelog"));
logs.addSink(StreamingFileSink.forRowFormat(
new Path("D:\\develop\\projects\\flink-study-project\\src\\resources\\simplelog"),
new SimpleStringEncoder<VisitorLog>()).build());
deleteFile(new File("D:\\develop\\projects\\flink-study-project\\src\\resources\\simplelogtext"));
logs.writeAsText("D:\\develop\\projects\\flink-study-project\\src\\resources\\simplelogtext");
2.将数据写入实时存储组件(kafka,datahub)
这种写入方法是企业中常用的,先将数据写入中间缓存组件,然后下游可以rds来订阅kafka,我们一般不直接将数据写入rds,因为实时的量不是定值,而是按照用户访问习惯会出现高低峰,我们如果在高峰的时候,下游写数据rds接受的数据量太多,而导致写入数据变慢,那么按照反压机制,上游数据处理也会变慢,读取源数据也会变慢。最后导致的是实时数据或者实时大屏数据延迟过而不准确,就失去了实时的目标。
/**
* 2.数据写入kafka
* 将数据写入kafka
* 注意:addsink方法的FlinkKafkaProducer011类参数需要和第三个参数字段类型保持一致
* 如果前面是string,后面也是string类型。如果需要写入特殊类型,那么后面的参数也需要自己实现一个特殊类型的
* 字段
*/
DataStream<String> dealStream = logs.map(new MapFunction<VisitorLog, String>() {
@Override
public String map(VisitorLog value) throws Exception {
return value.toString();
}
});
dealStream.addSink(new FlinkKafkaProducer011<String>("pc:9092","deal_log",
new SimpleStringSchema()));
3.自定义sink(JDBCSink)
和source同理,flink没有全部支持大数据生态,有时候也需要我们来自定义组件。实现的话需要继承RichSinkFunction类,并实现三个核心方法。open,close,invoke
package com.keino.apiTest;
import com.keino.entitys.VisitorLog;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class MysqlSink extends RichSinkFunction<VisitorLog> {
Connection conn = null;
PreparedStatement insertSql = null;
PreparedStatement updateSql = null;
/**
* 初始化操作 建立连接 生成语句句柄
* @param parameters
* @throws Exception
*/
@Override
public void open(Configuration parameters) throws Exception {
conn = DriverManager.getConnection("jdbc:mysql://pc:3306/flink","root","root");
String sql = "insert into flink_test(name) values(?)";
insertSql = conn.prepareStatement(sql);
}
/**
* 释放连接 收尾工作
* @throws Exception
*/
@Override
public void close() throws Exception {
conn.close();
insertSql.close();
}
/**
* 正式插入语句
* @param value
* @param context
* @throws Exception
*/
@Override
public void invoke(VisitorLog value, Context context) throws Exception {
insertSql.setString(1,value.url);
int affect = insertSql.executeUpdate();
}
}
/**
* 3.将数据写入mysql中
*
*/
logs.addSink(new MysqlSink());
env.execute();
温馨提示
–>完整代码