一、背景说明

Flink的API做了4层的封装,上两层TableAPI、SQL语法相对简单便于编写,面对小需求可以快速上手解决,本文参考官网及部分线上教程编写source端、sink端代码,分别读取socket、kafka及文本作为source,并将流数据输出写入Kafka、ES及MySQL,方便后续查看使用。

二、代码部分

说明:这里使用connect及DDL两种写法,connect满足Flink1.10及以前版本使用,目前官方文档均是以DDL写法作为介绍,建议1.10以后的版本使用DDL写法操作,通用性更强。

1.读取(Source)端写法

1.1 基础环境建立,方便演示并行度为1且不设置CK

  1. //建立Stream环境,设置并行度为1
  2. StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment().setParallelism(1);
  3. //建立Table环境
  4. StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);

1.2 读取Socket端口数据,并使用TableAPI及SQL两种方式查询

  1. //读取服务器9999端口数据,并转换为对应JavaBean
  2. SingleOutputStreamOperator<WaterSensor> mapDS = env.socketTextStream("hadoop102", 9999)
  3. .map(value -> {
  4. String[] split = value.split(",");
  5. return new WaterSensor(split[0]
  6. , Long.parseLong(split[1])
  7. , Integer.parseInt(split[2]));});
  8. //创建表:将流转换成动态表。
  9. Table table = tableEnv.fromDataStream(mapDS);
  10. //对动态表进行查询,TableAPI方式
  11. Table selectResult = table.where($("id").isEqual("ws_001")).select($("id"), $("ts"), $("vc"));
  12. //对动态表镜像查询,SQL方式-未注册表
  13. Table selectResult = tableEnv.sqlQuery("select * from " + table);

1.3 读取文本(FileSystem)数据,并使用TableAPI进行查询

  1. //Flink1.10写法使用connect方式,读取txt文件并建立临时表
  2. tableEnv.connect(new FileSystem().path("input/sensor.txt"))
  3. .withFormat(new Csv().fieldDelimiter(',').lineDelimiter("\n"))
  4. .withSchema(new Schema().field("id", DataTypes.STRING())
  5. .field("ts", DataTypes.BIGINT())
  6. .field("vc",DataTypes.INT()))
  7. .createTemporaryTable("sensor");
  8. //转换成表对象,对表进行查询。SQL写法参考Socket段写法
  9. Table table = tableEnv.from("sensor");
  10. Table selectResult = table.groupBy($("id")).aggregate($("id").count().as("id_count"))select($("id"), $("id_count"));

1.4 消费Kafka数据,并使用TableAPI进行查询,分别用conncet及DDL写法

  1. //Flink1.10写法使用connect方式,消费kafka对应主题并建立临时表
  2. tableEnv.connect(new Kafka().version("universal")
  3. .topic("sensor")
  4. .startFromLatest()
  5. .property(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092")
  6. .property(ConsumerConfig.GROUP_ID_CONFIG,"BD"))//消费者组
  7. .withSchema(new Schema().field("id", DataTypes.STRING())
  8. .field("ts", DataTypes.BIGINT())
  9. .field("vc",DataTypes.INT()))
  10. .withFormat(new Csv())
  11. .createTemporaryTable("sensor");
  12. //Flink1.10以后使用DDL写法
  13. tableEnv.executeSql("CREATE TABLE sensor (" +
  14. " `id` STRING," +
  15. " `ts` BIGINT," +
  16. " `vc` INT" +
  17. ") WITH (" +
  18. " 'connector' = 'kafka'," +
  19. " 'topic' = 'sensor'," +
  20. " 'properties.bootstrap.servers' = 'hadoop102:9092'," +
  21. " 'properties.group.id' = 'BD'," +
  22. " 'scan.startup.mode' = 'latest-offset'," +
  23. " 'format' = 'csv'" +
  24. ")");
  25. //转换成表对象,对表进行查询。SQL写法参考Socket段写法
  26. Table table = tableEnv.from("sensor");
  27. Table selectResult = table.groupBy($("id")).aggregate($("id").count().as("id_count"))
  28. .select($("id"), $("id_count"));

2.写入(Sink)端部分写法

2.1 写入文本文件

  1. //创建表:创建输出表,connect写法
  2. tableEnv.connect(new FileSystem().path("out/sensor.txt"))
  3. .withFormat(new Csv())
  4. .withSchema(new Schema().field("id", DataTypes.STRING())
  5. .field("ts", DataTypes.BIGINT())
  6. .field("vc",DataTypes.INT()))
  7. .createTemporaryTable("sensor");
  8. //将数据写入到输出表中即实现sink写入,selectResult则是上面source侧查询出来的结果表
  9. selectResult.executeInsert("sensor");

2.2 写入Kafka

  1. //connect写法
  2. tableEnv.connect(new Kafka().version("universal")
  3. .topic("sensor")
  4. .sinkPartitionerRoundRobin() //轮询写入
  5. .property(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092"))
  6. .withSchema(new Schema().field("id", DataTypes.STRING())
  7. .field("ts", DataTypes.BIGINT())
  8. .field("vc",DataTypes.INT()))
  9. .withFormat(new Json())
  10. .createTemporaryTable("sensor");
  11. //DDL写法
  12. tableEnv.executeSql("CREATE TABLE sensor (" +
  13. " `id` STRING," +
  14. " `ts` BIGINT," +
  15. " `vc` INT" +
  16. ") WITH (" +
  17. " 'connector' = 'kafka'," +
  18. " 'topic' = 'sensor'," +
  19. " 'properties.bootstrap.servers' = 'hadoop102:9092'," +
  20. " 'format' = 'json'" +
  21. ")");
  22. //将数据写入到输出表中即实现sink写入,selectResult则是上面source侧查询出来的结果表
  23. selectResult.executeInsert("sensor");

2.3 写入MySQL(JDBC方式,这里手动导入了mysql-connector-java-5.1.9.jar)

  1. //DDL
  2. tableEnv.executeSql("CREATE TABLE sink_sensor (" +
  3. " id STRING," +
  4. " ts BIGINT," +
  5. " vc INT," +
  6. " PRIMARY KEY (id) NOT ENFORCED" +
  7. ") WITH (" +
  8. " 'connector' = 'jdbc'," +
  9. " 'url' = 'jdbc:mysql://hadoop102:3306/test?useSSL=false'," +
  10. " 'table-name' = 'sink_test'," +
  11. " 'username' = 'root'," +
  12. " 'password' = '123456'" +
  13. ")");
  14. //将数据写入到输出表中即实现sink写入,selectResult则是上面source侧查询出来的结果表
  15. selectResult.executeInsert("sensor");

2.4 写入ES

  1. //connect写法
  2. tableEnv.connect(new Elasticsearch()
  3. .index("sensor")
  4. .documentType("_doc")
  5. .version("7")
  6. .host("localhost",9200,"http")
  7. //设置为1,每行数据都写入是方便客户端输出展示,生产勿使用
  8. .bulkFlushMaxActions(1))
  9. .withSchema(new Schema()
  10. .field("id", DataTypes.STRING())
  11. .field("ts", DataTypes.BIGINT())
  12. .field("vc",DataTypes.INT()))
  13. .withFormat(new Json())
  14. .inAppendMode()
  15. .createTemporaryTable("sensor");
  16. //DDL写法
  17. tableEnv.executeSql("CREATE TABLE sensor (" +
  18. " id STRING," +
  19. " ts BIGINT," +
  20. " vc INT," +
  21. " PRIMARY KEY (id) NOT ENFORCED" +
  22. ") WITH (" +
  23. " 'connector' = 'elasticsearch-7'," +
  24. " 'hosts' = 'http://localhost:9200'," +
  25. " 'index' = 'users'," +
  26. " 'sink.bulk-flush.max-actions' = '1')";)
  27. //将数据写入到输出表中即实现sink写入,selectResult则是上面source侧查询出来的结果表
  28. selectResult.executeInsert("sensor");

三、补充说明

依赖部分pom.xml

  1. <properties>
  2. <java.version>1.8</java.version>
  3. <maven.compiler.source>${java.version}</maven.compiler.source>
  4. <maven.compiler.target>${java.version}</maven.compiler.target>
  5. <flink.version>1.12.0</flink.version>
  6. <scala.version>2.12</scala.version>
  7. <hadoop.version>3.1.3</hadoop.version>
  8. <maven.compiler.source>8</maven.compiler.source>
  9. <maven.compiler.target>8</maven.compiler.target>
  10. </properties>
  11. <dependencies>
  12. <dependency>
  13. <groupId>org.apache.flink</groupId>
  14. <artifactId>flink-java</artifactId>
  15. <version>${flink.version}</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.apache.flink</groupId>
  19. <artifactId>flink-clients_${scala.version}</artifactId>
  20. <version>${flink.version}</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.elasticsearch</groupId>
  24. <artifactId>elasticsearch</artifactId>
  25. <version>7.8.0</version>
  26. </dependency>
  27. <!-- elasticsearch 的客户端 -->
  28. <dependency>
  29. <groupId>org.elasticsearch.client</groupId>
  30. <artifactId>elasticsearch-rest-high-level-client</artifactId>
  31. <version>7.8.0</version>
  32. </dependency>
  33. <!-- elasticsearch 依赖 2.x 的 log4j -->
  34. <dependency>
  35. <groupId>org.apache.logging.log4j</groupId>
  36. <artifactId>log4j-api</artifactId>
  37. <version>2.8.2</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.apache.logging.log4j</groupId>
  41. <artifactId>log4j-core</artifactId>
  42. <version>2.8.2</version>
  43. </dependency>
  44. <dependency>
  45. <groupId>com.fasterxml.jackson.core</groupId>
  46. <artifactId>jackson-databind</artifactId>
  47. <version>2.9.9</version>
  48. </dependency>
  49. <dependency>
  50. <groupId>org.apache.flink</groupId>
  51. <artifactId>flink-connector-elasticsearch7_${scala.version}</artifactId>
  52. <version>${flink.version}</version>
  53. </dependency>
  54. <dependency>
  55. <groupId>org.projectlombok</groupId>
  56. <artifactId>lombok</artifactId>
  57. <version>1.18.16</version>
  58. <scope>provided</scope>
  59. </dependency>
  60. <dependency>
  61. <groupId>org.apache.flink</groupId>
  62. <artifactId>flink-table-api-java-bridge_${scala.version}</artifactId>
  63. <version>${flink.version}</version>
  64. </dependency>
  65. <dependency>
  66. <groupId>org.apache.flink</groupId>
  67. <artifactId>flink-table-planner-blink_${scala.version}</artifactId>
  68. <version>${flink.version}</version>
  69. </dependency>
  70. <dependency>
  71. <groupId>org.apache.flink</groupId>
  72. <artifactId>flink-csv</artifactId>
  73. <version>${flink.version}</version>
  74. </dependency>
  75. <dependency>
  76. <groupId>org.apache.flink</groupId>
  77. <artifactId>flink-connector-kafka_${scala.version}</artifactId>
  78. <version>${flink.version}</version>
  79. </dependency>
  80. <dependency>
  81. <groupId>org.apache.flink</groupId>
  82. <artifactId>flink-json</artifactId>
  83. <version>${flink.version}</version>
  84. </dependency>
  85. </dependencies>
  86. </project>

学习交流,有任何问题还请随时评论指出交流。

FlinkSQL写入Kafka/ES/MySQL示例-JAVA的更多相关文章

  1. Java读文件写入kafka

    目录 Java读文件写入kafka 文件格式 pom依赖 java代码 Java读文件写入kafka 文件格式 840271 103208 0 0.0 insert 84e66588-8875-441 ...

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

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

  3. java实时监听日志写入kafka(转)

    原文链接:http://www.sjsjw.com/kf_cloud/article/020376ABA013802.asp 目的 实时监听某目录下的日志文件,如有新文件切换到新文件,并同步写入kaf ...

  4. java实现Kafka的消费者示例

    使用java实现Kafka的消费者 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 3 ...

  5. java实时监听日志写入kafka(多目录)

    目的 实时监听多个目录下的日志文件,如有新文件切换到新文件,并同步写入kafka,同时记录日志文件的行位置,以应对进程异常退出,能从上次的文件位置开始读取(考虑到效率,这里是每100条记一次,可调整) ...

  6. java实时监听日志写入kafka

    目的 实时监听某目录下的日志文件,如有新文件切换到新文件,并同步写入kafka,同时记录日志文件的行位置,以应对进程异常退出,能从上次的文件位置开始读取(考虑到效率,这里是每100条记一次,可调整) ...

  7. Flink RichSourceFunction应用,读关系型数据(mysql)数据写入关系型数据库(mysql)

    1. 写在前面 Flink被誉为第四代大数据计算引擎组件,即可以用作基于离线分布式计算,也可以应用于实时计算.Flink的核心是转化为流进行计算.Flink三个核心:Source,Transforma ...

  8. storm集成kafka的应用,从kafka读取,写入kafka

    storm集成kafka的应用,从kafka读取,写入kafka by 小闪电 0前言 storm的主要作用是进行流式的实时计算,对于一直产生的数据流处理是非常迅速的,然而大部分数据并不是均匀的数据流 ...

  9. Spark(二十一)【SparkSQL读取Kudu,写入Kafka】

    目录 SparkSQL读取Kudu,写出到Kafka 1. pom.xml 依赖 2.将KafkaProducer利用lazy val的方式进行包装, 创建KafkaSink 3.利用广播变量,将Ka ...

随机推荐

  1. 【axios】get/post请求params/data传参总结

    axios中get/post请求方式 1. 前言 最近突然发现post请求可以使用params方式传值,然后想总结一下其中的用法. 2.1 分类 get请求中没有data传值方式 2.2 get请求 ...

  2. pr中打开Audition编辑剪辑?

    前景 现在一般的adobe全家桶都是一键安装破解. 天翼网盘链接,下载不限速,没有账号就现注册一个即可. https://cloud.189.cn/t/UZRjuqAZ3E7r (访问码:8ago) ...

  3. zTree增加树形菜单格式

    result为json字符串 //展示树形菜单 function showMenuTree(result) { console.log("页面展示函数:"+result); //属 ...

  4. @NotNull 、@NotBlank、@NotEmpty区别

    @NotNull: 主要用在基本数据类型上(Integer.Double...) 不能为null,但可以为empty 举例: @NotNull(message = "标题不能为空" ...

  5. 如何使用java搭建一款高性能的Mqtt集群broker!

    SMQTT是一款开源的MQTT消息代理Broker, SMQTT基于Netty开发,底层采用Reactor3反应堆模型,支持单机部署,支持容器化部署,具备低延迟,高吞吐量,支持百万TCP连接,同时支持 ...

  6. RTTI之typeid运算符

    1 #include <iostream> 2 #include <cstdlib> 3 #include <ctime> 4 #include <typei ...

  7. 透过“锁”事看InnoDB对并发的处理?

    一. 并发场景下的问题 相对于串行处理方式,并发的事务处理可显著提升数据库的事务吞吐量.提高资源利用率.在MySQL实际应用中,根据场景的不同,可以分为以下几类: 读读并发 读写并发 写写并发 在这些 ...

  8. 对spring创建对象时为何要使用接口

    对spring创建对象时为何要使用接口,而使用接口的实现类会报错 接上一篇问题的解答:Spring AOP获取不了增强类(额外方法)和无法通过getBean()获取对象 此问题发生在动态代理时,比如对 ...

  9. jQuery的入口和jQurey的对象切换

    jQuery jQuery的导入 通过script标签的src属性,link标签是导入层叠样式表 jQuery和原生JS的入口函数 1.jQ在页面结构加载完毕就会执行 原生JS的入口函数是等图片.层叠 ...

  10. systemd 进程管理详解

    systemd进程管理 systemd管理的优势 1.最新系统都采用systemd管理(RedHat7,CentOS7,Ubuntu15...) 2.CentOS7 支持开机并行启动服务,显著提高开机 ...