flink04 -----1 kafkaSource 2. kafkaSource的偏移量的存储位置 3 将kafka中的数据写入redis中去 4 将kafka中的数据写入mysql中去
1. kafkaSource
见官方文档
2. kafkaSource的偏移量的存储位置
默认存在kafka的特殊topic中,但也可以设置参数让其不存在kafka的特殊topic中


3 将kafka中的数据写入redis中去
redisSink不支持exactly Once,只支持AtLeast Once
KafkaSourceToRedisDemo

1 package cn._51doit.flink.day04;
2
3 import org.apache.flink.api.common.functions.FlatMapFunction;
4 import org.apache.flink.api.common.restartstrategy.RestartStrategies;
5 import org.apache.flink.api.common.serialization.SimpleStringSchema;
6 import org.apache.flink.api.java.tuple.Tuple;
7 import org.apache.flink.api.java.tuple.Tuple2;
8 import org.apache.flink.runtime.state.filesystem.FsStateBackend;
9 import org.apache.flink.streaming.api.CheckpointingMode;
10 import org.apache.flink.streaming.api.datastream.DataStreamSource;
11 import org.apache.flink.streaming.api.datastream.KeyedStream;
12 import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
13 import org.apache.flink.streaming.api.environment.CheckpointConfig;
14 import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
15 import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
16 import org.apache.flink.streaming.connectors.redis.RedisSink;
17 import org.apache.flink.streaming.connectors.redis.common.config.FlinkJedisPoolConfig;
18 import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommand;
19 import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommandDescription;
20 import org.apache.flink.streaming.connectors.redis.common.mapper.RedisMapper;
21 import org.apache.flink.util.Collector;
22
23 import java.util.Properties;
24
25 //运行该程序要传入5个参数:ckdir gid topic redishost redisport
26 public class KafkaSourceToRedisDemo {
27
28 public static void main(String[] args) throws Exception{
29
30 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
31
32 //如果开启Checkpoint,偏移量会存储到哪呢?
33 env.enableCheckpointing(30000);
34 env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.AT_LEAST_ONCE);
35 //就是将job cancel后,依然保存对应的checkpoint数据
36 env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
37 env.setStateBackend(new FsStateBackend(args[0]));
38 env.setRestartStrategy(RestartStrategies.fixedDelayRestart(10, 30000));
39
40 Properties properties = new Properties();
41 properties.setProperty("bootstrap.servers", "node-1.51doit.cn:9092,node-2.51doit.cn:9092,node-3.51doit.cn:9092");
42 properties.setProperty("group.id", args[1]);
43 properties.setProperty("auto.offset.reset", "earliest");
44 //properties.setProperty("enable.auto.commit", "false");
45 //如果没有开启checkpoint功能,为了不重复读取数据,FlinkKafkaConsumer会将偏移量保存到了Kafka特殊的topic中(__consumer_offsets)
46 //这种方式没法实现Exactly-Once
47 FlinkKafkaConsumer<String> flinkKafkaConsumer = new FlinkKafkaConsumer<String>(args[2], new SimpleStringSchema(), properties);
48
49 //在Checkpoint的时候将Kafka的偏移量保存到Kafka特殊的Topic中,默认是true
50 flinkKafkaConsumer.setCommitOffsetsOnCheckpoints(false);
51
52 DataStreamSource<String> lines = env.addSource(flinkKafkaConsumer);
53
54 SingleOutputStreamOperator<Tuple2<String, Integer>> wordAndOne = lines.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
55 @Override
56 public void flatMap(String line, Collector<Tuple2<String, Integer>> out) throws Exception {
57 String[] words = line.split(" ");
58 for (String word : words) {
59 out.collect(Tuple2.of(word, 1));
60 }
61 }
62 });
63
64 KeyedStream<Tuple2<String, Integer>, Tuple> keyed = wordAndOne.keyBy(0);
65
66 SingleOutputStreamOperator<Tuple2<String, Integer>> summed = keyed.sum(1);
67 //Transformation 结束
68 //调用RedisSink将计算好的结果保存到Redis中
69
70 //创建Jedis连接的配置信息
71 FlinkJedisPoolConfig conf = new FlinkJedisPoolConfig.Builder()
72 .setHost(args[3])
73 .setPassword(args[4])
74 .build();
75
76 summed.addSink(new RedisSink<>(conf, new RedisWordCountMapper()));
77
78 env.execute("KafkaSourceDemo");
79
80 }
81
82
83 public static class RedisWordCountMapper implements RedisMapper<Tuple2<String, Integer>> {
84
85 @Override
86 public RedisCommandDescription getCommandDescription() {
87 //指定写入Redis中的方法和最外面的大key的名称
88 return new RedisCommandDescription(RedisCommand.HSET, "wc");
89 }
90
91 @Override
92 public String getKeyFromData(Tuple2<String, Integer> data) {
93 return data.f0; //将数据中的哪个字段作为key写入
94 }
95
96 @Override
97 public String getValueFromData(Tuple2<String, Integer> data) {
98 return data.f1.toString(); //将数据中的哪个字段作为value写入
99 }
100 }
101 }
注意,在任务取消后,checkpoint中的数据会被删除掉,为了不让checkpoint中的数据被删除,可以设置如下参数
//就是将job cancel后,依然保存对应的checkpoint数据
env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
验证发现,解释redis使用的是At Least Once ,基于redis的幂等性(覆盖),其也能达到exactly once的目的
因此At Least Once结合redis的幂等性。可以实现exactly once的功能
问题:在checkpoint时,Flink怎么保证operator state和keyed state是一致的?
Flink为了在checkpoint时,实现数据一致性时,其会将source阻断(barrier机制),相当于将source节流(barrier),并且下游所有算子计算完才进行checkpoint,这样就能保证数据一致
4 将kafka中的数据写入mysql中去
KafkaSourceToMySQLDemo

package cn._51doit.flink.day04; import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.restartstrategy.RestartStrategies;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.api.java.tuple.Tuple;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.runtime.state.filesystem.FsStateBackend;
import org.apache.flink.streaming.api.CheckpointingMode;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.CheckpointConfig;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import org.apache.flink.streaming.connectors.redis.RedisSink;
import org.apache.flink.streaming.connectors.redis.common.config.FlinkJedisPoolConfig;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommand;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommandDescription;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisMapper;
import org.apache.flink.util.Collector; import java.util.Properties; //运行该程序要传入5个参数:ckdir gid topic redishost redisport
public class KafkaSourceToMySQLDemo { public static void main(String[] args) throws Exception{ StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); //如果开启Checkpoint,偏移量会存储到哪呢?
env.enableCheckpointing(30000);
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.AT_LEAST_ONCE);
//就是将job cancel后,依然保存对应的checkpoint数据
env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
env.setStateBackend(new FsStateBackend(args[0]));
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(10, 30000)); Properties properties = new Properties();
properties.setProperty("bootstrap.servers", "node-1.51doit.cn:9092,node-2.51doit.cn:9092,node-3.51doit.cn:9092");
properties.setProperty("group.id", args[1]);
properties.setProperty("auto.offset.reset", "earliest");
//properties.setProperty("enable.auto.commit", "false");
//如果没有开启checkpoint功能,为了不重复读取数据,FlinkKafkaConsumer会将偏移量保存到了Kafka特殊的topic中(__consumer_offsets)
//这种方式没法实现Exactly-Once
FlinkKafkaConsumer<String> flinkKafkaConsumer = new FlinkKafkaConsumer<String>(args[2], new SimpleStringSchema(), properties); //在Checkpoint的时候将Kafka的偏移量保存到Kafka特殊的Topic中,默认是true
flinkKafkaConsumer.setCommitOffsetsOnCheckpoints(false); DataStreamSource<String> lines = env.addSource(flinkKafkaConsumer); SingleOutputStreamOperator<Tuple2<String, Integer>> wordAndOne = lines.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
@Override
public void flatMap(String line, Collector<Tuple2<String, Integer>> out) throws Exception {
String[] words = line.split(" ");
for (String word : words) {
out.collect(Tuple2.of(word, 1));
}
}
}); KeyedStream<Tuple2<String, Integer>, Tuple> keyed = wordAndOne.keyBy(0); SingleOutputStreamOperator<Tuple2<String, Integer>> summed = keyed.sum(1);
//Transformation 结束
//调用MySQLSink将计算好的结果保存到MySQL中
summed.addSink(new MySqlSink()); env.execute("KafkaSourceToMySQLDemo"); } }
MySqlSink

package cn._51doit.flink.day04; import org.apache.flink.api.java.tuple.Tuple2;
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<Tuple2<String, Integer>> { private Connection connection = null;
@Override
public void open(Configuration parameters) throws Exception {
//可以创建数据库连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata?characterEncoding=UTF-8", "root", "123456"); } @Override
public void invoke(Tuple2<String, Integer> value, Context context) throws Exception { PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO t_wordcount VALUES (?, ?) ON DUPLICATE KEY UPDATE counts = ?");
preparedStatement.setString(1, value.f0);
preparedStatement.setLong(2, value.f1);
preparedStatement.setLong(3, value.f1);
preparedStatement.executeUpdate();
preparedStatement.close();
} @Override
public void close() throws Exception {
connection.close();
} }
flink04 -----1 kafkaSource 2. kafkaSource的偏移量的存储位置 3 将kafka中的数据写入redis中去 4 将kafka中的数据写入mysql中去的更多相关文章
- 大数据学习day33----spark13-----1.两种方式管理偏移量并将偏移量写入redis 2. MySQL事务的测试 3.利用MySQL事务实现数据统计的ExactlyOnce(sql语句中出现相同key时如何进行累加(此处时出现相同的单词))4 将数据写入kafka
1.两种方式管理偏移量并将偏移量写入redis (1)第一种:rdd的形式 一般是使用这种直连的方式,但其缺点是没法调用一些更加高级的api,如窗口操作.如果想更加精确的控制偏移量,就使用这种方式 代 ...
- MYSQL的常用命令和增删改查语句和数据类型
连接命令:<a href="http://lib.csdn.net/base/mysql" class='replace_word' title="MySQL知识库 ...
- MYSQL的常用命令和增删改查语句和数据类型【转】
连接命令:<a href="http://lib.csdn.net/base/mysql" class='replace_word' title="MySQL知识库 ...
- Parquet与ORC:高性能列式存储格式(收藏)
背景 随着大数据时代的到来,越来越多的数据流向了Hadoop生态圈,同时对于能够快速的从TB甚至PB级别的数据中获取有价值的数据对于一个产品和公司来说更加重要,在Hadoop生态圈的快速发展过程中,涌 ...
- 数据库开发 MySQL
MySQL是Web世界中使用最广泛的数据库服务器.SQLite的特点是轻量级.可嵌入,但不能承受高并发访问,适合桌面和移动应用.而MySQL是为服务器端设计的数据库,能承受高并发访问,同时占用的内存也 ...
- Android学习总结——文件储存
Android中文件存储的操作: 1.Activity的openFileOutput()方法可以把数据输出到文件中2.创建的文件保存在/data/data/<package name>/f ...
- MySQL InnoDB 索引原理
本文由 网易云发布. 作者:范鹏程,网易考拉海购 InnoDB是 MySQL最常用的存储引擎,了解InnoDB存储引擎的索引对于日常工作有很大的益处,索引的存在便是为了加速数据库行记录的检索.以下是 ...
- JDK1.8 HashMap源码分析
一.HashMap概述 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时 ...
- solidity learning (1)
学习文档笔记:http://solidity-cn.readthedocs.io/zh/develop/layout-of-source-files.html 1.pragma solidity ^0 ...
随机推荐
- loto仪器_如何模拟输出凸轮轴和曲轴波形_用任意波形信号源SIG852?
loto仪器_如何模拟输出凸轮轴和曲轴波形_用任意波形信号源SIG852? 在汽车传感器的波形检测应用中,有时候需要模拟各种汽车传感器的输出信号,用来驱动和监测对应的执行机构或者电路是否正常,这其中, ...
- prometheus(5)之consul服务自动发现及pushgetway
pushgetway(push上传metric数据) Pushgateway简介 Pushgateway是prometheus的一个组件,prometheus server默认是通过exporter主 ...
- .net core api 请求实现接口幂等性
简单实现接口幂等性,根据参数的hascode实现: 参数介绍 WaitMillisecond : 请求等待毫秒数 CacheMillisecond:请求结果缓存毫秒数 参数具体使用场景 WaitMi ...
- 用js实现web端录屏
用js实现web端录屏 原创2021-11-14 09:30·无意义的路过 随着互联网技术飞速发展,网页录屏技术已趋于成熟.例如可将录屏技术运用到在线考试中,实现远程监考.屏幕共享以及录屏等:而在我们 ...
- More Effective C++笔记(二)
三.异常 条款9:利用destructor避免泄露资源 把资源封装在对象内,通常可以在exception出现时避免资源泄露 条款10:在构造函数内阻止资源泄露 C++仅仅能删除被完全构造的对象(ful ...
- Python基础(条件判断)
# age = 103 # if age < 90: # print('%s小于90' %age) # elif age > 90 and age < 95: # print('%s ...
- Prometheus的监控解决方案(含监控kubernetes)
prometheus的简介和安装 Prometheus(普罗米修斯)是一个开源系统监控和警报工具,最初是在SoundCloud建立的.自2012年成立以来,许多公司和组织都采用了普罗米修斯,该项目拥有 ...
- int,double与机器字长
机器字长:计算机能直接处理的二进制数据的位数,它决定了计算机的运算精度想深入了解. 学好汇编语言对你帮助非常大.汇编语言中的,最基本的数据类型有: (1) byte (2)word (3)double ...
- 【华为昇腾】 序言:从昇腾AI软硬件平台聊起
2021年是很值得纪念的一年,从上半年开始跟随导师编写有关华为昇腾软件栈CANN的教材,一年的时间反复迭代 终于快要出版了. 这一系列博客可以视作我从编者的角度,重新梳理的全书思路.明年入职商汤之后要 ...
- [cf720D]Slalom
对于每一行,这些障碍将其划分为若干段,记第$i$行($y=i$时)从左到右第$j$段为$[l_{i,j},r_{i,j}]$ 显然一条路径恰好经过每一行中的一段,且两种方案不同当且仅当其中经过的一段不 ...