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. DDR3 IP和CIC IP仿真问题解决记录

    1.更新vivado的仿真库(data/secureip和verilog和vhdl文件夹)至最新的vivado库和生成IP的版本匹配: 2.vcs编译脚本里面把仿真库地址指向匹配的仿真库版本: 3.v ...

  2. Luogu P1563 [NOIp2016提高组]玩具谜题 | 模拟

    题目链接 纯模拟题,没啥好说的,就是要判断地方有点多,一定要注意细节. #include<iostream> #include<cstdio> #include<fstr ...

  3. Docker 18.03 Centos7.6 安装 内网

    首先访问https://download.docker.com/linux/centos/7/x86_64/stable/Packages/获取对应版本的rpm包docker包docker-ce-18 ...

  4. Typecho部署小破站

    写在前面 以前利用 Github Page + Hexo框架 + Next主题搭建过静态博客,没错就是那个黑白色系的网页!但是体验并不是很好,一来本身是静态网页,页面内容要修改都需要在本地修改完上传到 ...

  5. 近期业务大量突增微服务性能优化总结-4.增加对于同步微服务的 HTTP 请求等待队列的监控

    最近,业务增长的很迅猛,对于我们后台这块也是一个不小的挑战,这次遇到的核心业务接口的性能瓶颈,并不是单独的一个问题导致的,而是几个问题揉在一起:我们解决一个之后,发上线,之后发现还有另一个的性能瓶颈问 ...

  6. 【Go语言学习笔记】函数做参数和闭包

    函数做参数 在Go语言中,函数也是一种数据类型,我们可以通过type来定义它,它的类型就是所有拥有相同的参数,相同的返回值的一种类型.类似于重写(同名覆盖). 回调函数:函数有一个参数是函数类型,这个 ...

  7. 『学了就忘』Linux基础命令 — 31、grep命令和通配符

    目录 1.grep命令介绍 2.find命令和grep命令的区别(重点) (1)find命令 (2)grep命令 3.通配符与正则表达式的区别 (1)通配符: (2)正则表达式: 1.grep命令介绍 ...

  8. [JavaScript闭包]Javascript闭包的判别,作用和示例

    闭包是JavaScript最重要的特性之一,也是全栈/前端/JS面试的考点. 那闭包究竟该如何理解呢? 如果不爱看文字,喜欢看视频.那本文配套讲解视频已发送到B站上供大家参考学习. 如果觉得有所收获, ...

  9. 巧用Python快速构建网页服务器

    经常做web开发,要调试一个网页,直接打开文件,用file模式显然是业余的. 但动辄要部署个IIS或APACHE站点,也确实太累,怎么办? 逐浪君此前有分享过通过http-server来构建快速的we ...

  10. python-文件操作(一)

    目录 文件操作 1.什么是文件? 2.操作文件的方法: 3.路径分类: 4.如何取消特殊字符的功能: 5.对文件的操作有:读.写.追加内容 6.with上下文管理 7.文件操作方法详细: 1.r-读操 ...