Flink-输出算子(Sink)使用
创始人
2024-01-30 19:16:43

5.5 输出算子

5.5.1 概述

  1. print也是一种输出类PrintSinkFunction
    image.png

创建了一个PrintSinkFunction操作,然后调用addSink方法的作为传入参数
image.png

PrintSinkFunction这个类继承自RichSinkFunction富函数类

  1. RichSourceFunction类

image.png

  • 继承了AbstractRichFunction富函数类

因此就可以调用富函数类的声明周期方法,例如open,close,以及获取运行时上下文,运行环境,定义状态等等

  • RichSourceFunction类又实现了SinkFunction这个接口,所以本质上也是SinkFunction

image.png

image.png

  • SinkFunction接口的抽象方法有invoke,传入是value,以及当前的上下文
  1. 如果需要自定义输出算子
    image.png

可以调用DataStream的addSink方法

image.png
然后传入自己实现的SinkFunction

  1. flink提供的第三方系统连接器

image.png

5.5.2 输出到文件

  1. StreamFileSink流失文件输出类
  • 来源

继承RichSinkFunction类,并实现CheckpointedFunction,CheckpointListener(检查点)

image.png

  • 底层

底层将数据写入bucket(桶),桶里面分大小存储分区文件,实现了分布式存储

  • 创建实例

使用Builder构建器构建

image.png

image.png)

RowFormatBuilder是行编码

image.png

BulkFormatBuilder是列存储编码格式

  1. 代码

image.png

public class SinkToFileTest {public static void main(String[] args) throws Exception{StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(4);DataStreamSource stream = env.fromElements(new Event("Mary", "./home", 1000L),new Event("Bob", "./cart", 2000L),new Event("Alice", "./prod?id=100", 3000L),new Event("Bob", "./prod?id=1", 3300L),new Event("Alice", "./prod?id=200", 3000L),new Event("Bob", "./home", 3500L),new Event("Bob", "./prod?id=2", 3800L),new Event("Bob", "./prod?id=3", 4200L));//2.为了得到并传入SinkFunction,需要构建StreamingFileSink的一个对象//调用forRowFormat方法或者forBulkformat方法得到一个DefaultRowFormatBuilder//  其中forBulkformat方法前面还有类型参数,以及传参要求一个目录名称,一个编码器//写入文件需要序列化,需要定义序列化方法并进行编码转换,当成Stream写入文件//然后再使用builder创建实例StreamingFileSink streamingFileSink = StreamingFileSink.forRowFormat(new Path("./output"),new SimpleStringEncoder<>("UTF-8")).withRollingPolicy(//指定滚动策略,根据事件或者文件大小新产生文件归档保存DefaultRollingPolicy.builder()//使用builder构建实例.withMaxPartSize(1024 * 1024 * 1024).withRolloverInterval(TimeUnit.MINUTES.toMinutes(15))//事件间隔毫秒数.withInactivityInterval(TimeUnit.MINUTES.toMinutes(15))//当前不活跃的间隔事件,隔多长事件没有数据到来.build()).build();//1.写入文件调用addSink()方法,并传入SinkFunctionstream.map(data -> data.toString())//把Event类型转换成String.addSink(streamingFileSink);env.execute();}
}
  • 结果

image.png

5.5.3 输出到kafka

image.png

  1. 代码
public class SinkToKafka {public static void main(String[] args) throws Exception{StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);//1.从kafka中读取数据Properties properties = new Properties();properties.setProperty("bootstrap.servers","hadoop2:9092");properties.setProperty("group.id", "consumer-group");DataStreamSource kafkaStream = env.addSource(new FlinkKafkaConsumer("clicks", new SimpleStringSchema(), properties));//2.用flink进行简单的etl处理转换SingleOutputStreamOperator result = kafkaStream.map(new MapFunction() {@Overridepublic String map(String value) throws Exception {String[] fields = value.split(",");return new Event(fields[0].trim(), fields[1].trim(), Long.valueOf(fields[2].trim())).toString();}});//3.结果数据写入kafka//FlinkKafkaProducer传参borckList,topicid,序列化result.addSink(new FlinkKafkaProducer("hadoop2:9092","events",new SimpleStringSchema()));env.execute();}
}
  1. kafka输出结果
    image.png

5.5.4 输出到redis

  1. 引入依赖
org.apache.bahirflink-connector-redis_2.111.0

  1. 代码
    image.png
    继承自RichSinkFunction
    image.png

去调构造方法,换入redis集群的配置FlinkJedisConfigBase以及RedisMapper写入命令

image.png

FlinkJedisPoolConfig用这个没毛病,直接继承的FlinkJedisConfigBase

image.png

  1. 代码
public class SinkToRedis {public static void main(String[] args) throws Exception{StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);//1.输入ClickSource是自定义输入DataStreamSource stream = env.addSource(new ClickSource());//2.创建一个jedis连接配置//FlinkJedisPoolConfig直接继承的FlinkJedisConfigBaseFlinkJedisPoolConfig config = new FlinkJedisPoolConfig.Builder().setHost("hadoop2").build();//3.写入redisstream.addSink(new RedisSink<>(config,new MyRedisMapper()));env.execute();}//3.自定义类实现 redisMapper接口public static class MyRedisMapper implements RedisMapper{@Overridepublic RedisCommandDescription getCommandDescription() {return new RedisCommandDescription(RedisCommand.HSET,"clicks");//写入哈希表}@Overridepublic String getKeyFromData(Event data) {return data.user;}@Overridepublic String getValueFromData(Event data) {return data.url;}}
}
  1. 结果

image.png

5.5.5 输出到ElasticSearch

  1. 引入依赖
org.apache.flink 
flink-connector-elasticsearch6_${scala.binary.version}
${flink.version}

  1. 代码
    image.png

image.png

传入参数是List和ElasticsearchSinkFunction


image.png

image.png

public class SinToES {public static void main(String[] args) throws Exception{StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);//1.输入DataStreamSource stream = env.fromElements(new Event("Mary", "./home", 1000L),new Event("Bob", "./cart", 2000L),new Event("Alice", "./prod?id=100", 3000L),new Event("Bob", "./prod?id=1", 3300L),new Event("Alice", "./prod?id=200", 3000L),new Event("Bob", "./home", 3500L),new Event("Bob", "./prod?id=2", 3800L),new Event("Bob", "./prod?id=3", 4200L));//2.定义hosts的列表ArrayList httpHosts = new ArrayList<>();httpHosts.add(new HttpHost("hadoop",9200));//3.定义ElasticsearchSinkFunction,是个接口,重写process方法//向es发送请求,并插入数据ElasticsearchSinkFunction elasticsearchSinkFunction = new ElasticsearchSinkFunction() {@Override//输入,运行上下文,发送任务请求public void process(Event element, RuntimeContext ctx, RequestIndexer indexer) {HashMap map = new HashMap<>();map.put(element.user, element.url);//构建一个indexrequestIndexRequest request = Requests.indexRequest().index("clicks").type("types").source(map);indexer.add(request);}};//4.写入es//传入参数是List和ElasticsearchSinkFunctionstream.addSink(new ElasticsearchSink.Builder<>(httpHosts,elasticsearchSinkFunction).build());env.execute();}
}
  1. 结果

image.png

image.png

5.5.6 输入到Mysql

  1. 引入依赖
org.apache.flinkflink-connector-jdbc_${scala.binary.version}${flink.version}

mysqlmysql-connector-java5.1.47

  1. 代码

image.png

三个参数,sql,JdbcStatementBuilder构造,JdbcConnectionOptions等sql的连接配置
image.png

image.png

单一抽象方法,lambda使用

public class SinkToMysql {public static void main(String[] args) throws Exception{StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);//1.输入DataStreamSource stream = env.fromElements(new Event("Mary", "./home", 1000L),new Event("Bob", "./cart", 2000L),new Event("Alice", "./prod?id=100", 3000L),new Event("Bob", "./prod?id=1", 3300L),new Event("Alice", "./prod?id=200", 3000L),new Event("Bob", "./home", 3500L),new Event("Bob", "./prod?id=2", 3800L),new Event("Bob", "./prod?id=3", 4200L));//三个参数,sql,JdbcStatementBuilder构造,JdbcConnectionOptions等sql的连接配置stream.addSink(JdbcSink.sink("INSERT INTO clicks (user,url) VALUES(?,?)",((statement,event)->{statement.setString(1,event.user);statement.setString(2,event.url);}),new JdbcConnectionOptions.JdbcConnectionOptionsBuilder().withUrl("jdbc:mysql://localhost:3306/test2").withDriverName("com.mysql.jdbc.Driver").withUsername("root").withPassword("123456").build()));env.execute();}
}
  1. mysql前期准备
  • 创建mysql的test2
  • 创建clicks表
mysql> create table clicks(-> user varchar(20) not null,-> url varchar(100) not null);
Query OK, 0 rows affected (0.02 sec)
  1. 结果
    image.png

5.5.7 自定义Sink输出

  1. 分析

调用DataStream的addSink()方法,并传入自定义好的SinkFunction(采用富函数类),重写关键方法invoke(),并且重写富函数类的生命周期相关方法open和close

  1. 导入依赖
org.apache.hbasehbase-client${hbase.version}

  1. 代码

相关内容

热门资讯

长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
1秒多少毫秒 1秒等于多少毫秒... 长度单位换算1丈=10尺;1尺=10寸;1寸=10分;1分=10厘;1丈≈3.33米;1尺≈3.33...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
中国电信人工电话多少 中国电信... 当我们在使用中国移动、中国电信和中国联通提供的电信业务时,可能会发生争议。建议直接向服务提供商投诉,...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...