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. 集合栈 牛客网 程序员面试金典 C++ Python

    集合栈 牛客网 程序员面试金典 C++ Python 题目描述 请实现一种数据结构SetOfStacks,由多个栈组成,其中每个栈的大小为size,当前一个栈填满时,新建一个栈.该数据结构应支持与普通 ...

  2. MySql数据库索引-聚集索引和辅助索引

    InnoDB存储引擎索引: B+树索引:不能找到一个给定键值的具体行,能找到的只是被查找数据行所在的页.然后把页加载到内存,在查询所要的数据. 全文索引: 哈希索引:InnoDB会根据表的使用情况自动 ...

  3. QuantumTunnel:内网穿透服务设计

    背景 最近工作中有公网访问内网服务的需求,便了解了内网穿透相关的知识.发现原理和实现都不复杂,遂产生了设计一个内网穿透的想法. 名字想好了,就叫QuantumTunnel,量子隧道,名字来源于量子纠缠 ...

  4. 文件与文件系统的压缩与打包 tar gzip bzip2

    1:linux下常见的压缩文件后缀: .gz .zip .bz2 打包后的: .tar.gz .tar.zip .tar.bz2 2:gzip: 压缩:gzip file 解压:gunzip file ...

  5. Qt5 项目程序打包发布 详细教程

    概述 当我们用QT写好了一个软件,要把你的程序分享出去的时候,不可能把编译的目录拷贝给别人去运行.编译好的程序应该是一个主程序,加一些资源文件,再加一些动态链接库,高大上一些的还可以做一个安装文件. ...

  6. this.$set用法

    this.$set()的主要功能是解决改变数据时未驱动视图的改变的问题,也就是实际数据被改变了,但我们看到的页面并没有变化,这里主要讲this.$set()的用法,如果你遇到类似问题可以尝试下,vue ...

  7. 为 Android 编译并集成 FFmpeg 的尝试与踩坑

    前言与环境说明 随着 FFmpeg.NDK 与 Android Studio 的不断迭代,本文可能也会像我参考过的过期文章一样失效(很遗憾),但希望本文中提到的问题排查以及步骤说明能够帮到你,如果发现 ...

  8. PTA 根据后序和中序遍历输出先序遍历 (25分)

    PTA 根据后序和中序遍历输出先序遍历 (25分) 本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果. 输入格式: 第一行给出正整数N(≤30),是树中结点的个数.随后两行 ...

  9. vue3 学习笔记 (二)——axios 的使用有变化吗?

    本篇文章主要目的就是想告诉我身边,正在学 vue3 或者 准备学 vue3 的同学,vue3中网络请求axios该如何使用,防止接触了一点点 vue3 的同学会有个疑问?生命周期.router .vu ...

  10. Python 中的反转字符串:reversed()、切片等

    摘要:以相反的顺序反转和处理字符串可能是编程中的一项常见任务.Python 提供了一组工具和技术,可以帮助您快速有效地执行字符串反转. 本文分享自华为云社区<Python 中的反转字符串:rev ...