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中去的更多相关文章

  1. 大数据学习day33----spark13-----1.两种方式管理偏移量并将偏移量写入redis 2. MySQL事务的测试 3.利用MySQL事务实现数据统计的ExactlyOnce(sql语句中出现相同key时如何进行累加(此处时出现相同的单词))4 将数据写入kafka

    1.两种方式管理偏移量并将偏移量写入redis (1)第一种:rdd的形式 一般是使用这种直连的方式,但其缺点是没法调用一些更加高级的api,如窗口操作.如果想更加精确的控制偏移量,就使用这种方式 代 ...

  2. MYSQL的常用命令和增删改查语句和数据类型

    连接命令:<a href="http://lib.csdn.net/base/mysql" class='replace_word' title="MySQL知识库 ...

  3. MYSQL的常用命令和增删改查语句和数据类型【转】

    连接命令:<a href="http://lib.csdn.net/base/mysql" class='replace_word' title="MySQL知识库 ...

  4. Parquet与ORC:高性能列式存储格式(收藏)

    背景 随着大数据时代的到来,越来越多的数据流向了Hadoop生态圈,同时对于能够快速的从TB甚至PB级别的数据中获取有价值的数据对于一个产品和公司来说更加重要,在Hadoop生态圈的快速发展过程中,涌 ...

  5. 数据库开发 MySQL

    MySQL是Web世界中使用最广泛的数据库服务器.SQLite的特点是轻量级.可嵌入,但不能承受高并发访问,适合桌面和移动应用.而MySQL是为服务器端设计的数据库,能承受高并发访问,同时占用的内存也 ...

  6. Android学习总结——文件储存

    Android中文件存储的操作: 1.Activity的openFileOutput()方法可以把数据输出到文件中2.创建的文件保存在/data/data/<package name>/f ...

  7. MySQL InnoDB 索引原理

    本文由  网易云发布. 作者:范鹏程,网易考拉海购 InnoDB是 MySQL最常用的存储引擎,了解InnoDB存储引擎的索引对于日常工作有很大的益处,索引的存在便是为了加速数据库行记录的检索.以下是 ...

  8. JDK1.8 HashMap源码分析

      一.HashMap概述 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时 ...

  9. solidity learning (1)

    学习文档笔记:http://solidity-cn.readthedocs.io/zh/develop/layout-of-source-files.html 1.pragma solidity ^0 ...

随机推荐

  1. Jetbrains 系 IDE 编辑器的代码提示功能

    著名的 Jetbrains 可谓编程界的一大福音,众多有名代码编辑器比如 ItelliJ IDEA.PHPStorm.WebStorm.PyCharm 等,均出自这家公司麾下. 对于中国的Java开发 ...

  2. maven项目打包执行

    1.maven项目已完成状态! 2.maven打包前提pom.xml引入插件依赖 <build> <plugins> <plugin> <artifactId ...

  3. PTA7-1 迷宫寻路 (20分)

    7-1 迷宫寻路 (20分) 给定一个M行N列的迷宫图,其中 "0"表示可通路,"1"表示障碍物,无法通行.在迷宫中只允许在水平或上下四个方向的通路上行走,走过 ...

  4. hudi clustering 数据聚集(三 zorder使用)

    目前最新的 hudi 版本为 0.9,暂时还不支持 zorder 功能,但 master 分支已经合入了(RFC-28),所以可以自己编译 master 分支,提前体验下 zorder 效果. 环境 ...

  5. 站长管理服务器必读:Ftp、Ftps与Sftp三兄弟的不同与区别以及部署全指引

    文章标题: 站长管理服务器必读:Ftp.Ftps与Sftp三兄弟的不同与区别以及部署全指引 关键字 : ftp,sftp,freesshd,ftps 文章分类: 教程 创建时间: 2020年3月23日 ...

  6. 菜鸡的Java笔记 第三十 - java 异常的捕获及处理

    异常的捕获及处理        1.异常的产生分析以及所带来的影响        2.异常的处理的基本格式        3.异常的处理流程        4.异常的处理模式        5.自定义 ...

  7. webpack--初试webpack( 核心、体验、资源打包)

    前言 webpack是当前前端项目中最常用的资源构建工具,从本文开始,来总结记录一下关于webpack的学习. 正文 1.webpack简介 webpack官网(https://webpack.doc ...

  8. python实现Canny边缘检测

    一,定义与概述 使用图像梯度的算法,在有些场景不适用,如检测大量头发边缘,边缘不够细腻.所以有人提出了Canny算法! 非极大值抑制,保留极大值 参考:https://www.cnblogs.com/ ...

  9. Java 操作符小记

    "在最底层,Java中的数据是通过使用操作符来操作的" (Thinking in Java) 1 算术操作符 Java 中的基本算术操作符和其他大多数程序设计语言是相同的.其中包括 ...

  10. [IIS]文件夹权限

    发布完iis,默认的 Application Pool 没有权限访问文件夹. 可以给项目文件夹添加用户权限. 右键 - "属性" - "安全" - " ...