Spark2.3(三十七):Stream join Stream(res文件每天更新一份)
kafka测试数据生成:
package com.dx.kafka; import java.util.Properties;
import java.util.Random; import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord; public class KafkaProducer {
public static void main(String[] args) throws InterruptedException {
Properties props = new Properties();
props.put("bootstrap.servers", "192.168.0.141:9092,192.168.0.142:9092,192.168.0.143:9092,192.168.0.144:9092");
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new org.apache.kafka.clients.producer.KafkaProducer(props);
int i = 0;
Random random=new Random();
while (true) {
i++;
producer.send(new ProducerRecord<String, String>("my-topic", "key-" + Integer.toString(i),
i%3+","+random.nextInt(100)));
System.out.println(i);
Thread.sleep(1000); if(i%100==0) {
Thread.sleep(60*1000);
}
}
// producer.close(); }
}
Stream join Stream测试代码:
要求:使用spark structured streaming实时读取kafka中的数据,kafka中的数据包含字段int_id;kafka上数据需要关联资源信息(通过kafka的int_id与资源的int_id进行关联),同时要求资源每天都更新。
使用spark structured streaming实时读取kafka中的数据
Dataset<Row> linesDF = this.sparkSession.readStream()//
.format("kafka")//
.option("failOnDataLoss", false)//
.option("kafka.bootstrap.servers", "192.168.0.141:9092,192.168.0.142:9092,192.168.0.143:9092,192.168.0.144:9092")//
.option("subscribe", "my-topic")//
.option("startingOffsets", "earliest")//
.option("maxOffsetsPerTrigger", 10)//
.load(); StructType structType = new StructType();
structType = structType.add("int_id", DataTypes.StringType, false);
structType = structType.add("rsrp", DataTypes.StringType, false);
structType = structType.add("mro_timestamp", DataTypes.TimestampType, false);
ExpressionEncoder<Row> encoder = RowEncoder.apply(structType);
Dataset<Row> mro = linesDF.select("value").as(Encoders.STRING()).map(new MapFunction<String, Row>() {
private static final long serialVersionUID = 1L; @Override
public Row call(String t) throws Exception {
List<Object> values = new ArrayList<Object>();
String[] fields = t.split(",");
values.add(fields.length >= 1 ? fields[0] : "null");
values.add(fields.length >= 2 ? fields[1] : "null");
values.add(new Timestamp(new Date().getTime())); return RowFactory.create(values.toArray());
}
}, encoder);
mro=mro.withWatermark("mro_timestamp", "15 minutes");
mro.printSchema();
加载资源信息
StructType resulStructType = new StructType();
resulStructType = resulStructType.add("int_id", DataTypes.StringType, false);
resulStructType = resulStructType.add("enodeb_id", DataTypes.StringType, false);
resulStructType = resulStructType.add("res_timestamp", DataTypes.TimestampType, false);
ExpressionEncoder<Row> resultEncoder = RowEncoder.apply(resulStructType);
Dataset<Row> resDs = sparkSession.readStream().option("maxFileAge", "1ms").textFile(resourceDir)
.map(new MapFunction<String, Row>() {
private static final long serialVersionUID = 1L; @Override
public Row call(String value) throws Exception {
String[] fields = value.split(",");
Object[] objItems = new Object[3];
objItems[0] = fields[0];
objItems[1] = fields[1];
objItems[2] = Timestamp.valueOf(fields[2]); return RowFactory.create(objItems);
}
}, resultEncoder);
resDs = resDs.withWatermark("res_timestamp", "1 seconds");
resDs.printSchema();
kafka上数据与资源关联
关联条件int_id相同,同时要求res.timestamp<=mro.timestmap & res.timestamp<(mro.timestmap-1天)
res如果放入broadcast经过测试发现也是可行的。
// JavaSparkContext jsc =
// JavaSparkContext.fromSparkContext(sparkSession.sparkContext());
Dataset<Row> cellJoinMro = mro.as("t10")//
.join(resDs.as("t11"),// jsc.broadcast(resDs).getValue()
functions.expr("t11.int_id=t10.int_id "//
+ "and t11.res_timestamp<=t10.mro_timestamp "//
+ "and timestamp_diff(t11.res_timestamp,t10.mro_timestamp,'>','-86400000')"),//
"left_outer")//
.selectExpr("t10.int_id", "t10.rsrp", "t11.enodeb_id", "t10.mro_timestamp", "t11.res_timestamp"); StreamingQuery query = cellJoinMro.writeStream().format("console").outputMode("update") //
.trigger(Trigger.ProcessingTime(1, TimeUnit.MINUTES))//
.start();
udf:timestamp_diff定义
sparkSession.udf().register("timestamp_diff", new UDF4<Timestamp, Timestamp, String, String, Boolean>() {
private static final long serialVersionUID = 1L; @Override
public Boolean call(Timestamp t1, Timestamp t2, String operator, String intervalMsStr) throws Exception {
long diffValue=t1.getTime()-t2.getTime();
long intervalMs=Long.valueOf(intervalMsStr); if(operator.equalsIgnoreCase(">")){
return diffValue>intervalMs;
}else if(operator.equalsIgnoreCase(">=")){
return diffValue>=intervalMs;
}else if(operator.equalsIgnoreCase("<")){
return diffValue<intervalMs;
}else if(operator.equalsIgnoreCase("<=")){
return diffValue<=intervalMs;
}else if(operator.equalsIgnoreCase("=")){
return diffValue==intervalMs;
}else{
throw new RuntimeException("unknown error");
}
}
},DataTypes.BooleanType);
如果删除资源历史数据,不会导致正在运行的程序抛出异常;当添加新文件到res hdfs路径下时,可以自动被加载进来。
备注:要求必须每天资源文件只能有一份,否则会导致kafka上数据关联后结果重复,同时,res上的每天的文件中包含timestmap字段格式都为yyyy-MM-dd 00:00:00。
Spark2.3(三十七):Stream join Stream(res文件每天更新一份)的更多相关文章
- jdk8系列三、jdk8之stream原理及流创建、排序、转换等处理
一.为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX ...
- [三]java8 函数式编程Stream 概念深入理解 Stream 运行原理 Stream设计思路
Stream的概念定义 官方文档是永远的圣经~ 表格内容来自https://docs.oracle.com/javase/8/docs/api/ Package java.util.s ...
- 微信小程序把玩(三十七)location API
原文:微信小程序把玩(三十七)location API location API也就分这里分两种wx.getLocation(object)获取当前位置和wx.openLocation(object) ...
- 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索
第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...
- NeHe OpenGL教程 第三十七课:卡通映射
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- spark三种连接Join
本文主要介绍spark join相关操作. 讲述spark连接相关的三个方法join,left-outer-join,right-outer-join,在这之前,我们用hiveSQL先跑出了结果以方便 ...
- Java进阶(三十七)java 自动装箱与拆箱
Java进阶(三十七)java 自动装箱与拆箱 前言 这个是jdk1.5以后才引入的新的内容.java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装称为装箱,解包装称为 ...
- Gradle 1.12用户指南翻译——第三十七章. OSGi 插件
本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- SQL注入之Sqli-labs系列第三十六关(基于宽字符逃逸GET注入)和三十七关(基于宽字节逃逸的POST注入)
0X1 查看源码 function check_quotes($string) { $string= mysql_real_escape_string($string); return $string ...
随机推荐
- python 全栈开发,Day32(知识回顾,网络编程基础)
一.知识回顾 正则模块 正则表达式 元字符 : . 匹配除了回车以外的所有字符 \w 数字字母下划线 \d 数字 \n \s \t 回车 空格 和 tab ^ 必须出现在一个正则表达式的最开始,匹配开 ...
- 《剑指offer》-递增数组中找到和为S的(最小)两个元素
题目描述 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输出描述: 对应每个测试案例,输出两个数,小的先输出. 首先 ...
- Eclipse中打包maven项目-war包方式
IntelliJ IDEA打包成war(包括maven项目)点击打开链接 首先要在maven项目中的pom.XML中配置好需要的配置: <project xmlns="http://m ...
- openstack Too many open files错误
oopenstack突然web页面无法打开,页面报500错误,查看httpd日志报如下错误 [Fri Feb ::] [:error] [pid ] [remote ] IOError: [Errno ...
- asp.net core session的使用
Session介绍 本文假设读者已经了解Session的概念和作用,并且在传统的.net framework平台上使用过. Asp.net core 1.0好像需要单独安装,在nuget控制台,选择你 ...
- Codeforces 295C Greg and Friends BFS
Greg and Friends BFS的过程中维护一下方案数. 我个人感觉不是很好想, 但是写出来之后怎么感觉这题这么SB啊啊. #include<bits/stdc++.h> #def ...
- 既有e^x又有sinx或cosx的积分题的解法
楼上三位,一致对e^x情有独钟,他们都是对的.通常,这类题既有e^x又有sinx或cosx的积分题,一般的解法是:1.选定e^x,或选定sinx.cosx,就得“从一而终”,用分部积分的方法计算, ...
- 缓存击穿、缓存失效及热点key的解决方案
分布式缓存是网站服务端经常用到的一种技术,在读多写少的业务场景中,通过使用缓存可以有效地支撑高并发的访问量,对后端的数据库等数据源做到很好地保护.现在市面上有很多分布式缓存,比如Redis.Memca ...
- [OpenCV-Python] OpenCV 中的图像处理 部分 IV (三)
部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 19 Canny 边缘检测 目标 • 了解 Canny 边缘检测的概念 • 学习函数 cv2.Canny() 1 ...
- hdu 6185 递推+【矩阵快速幂】
<题目链接> <转载于 >>> > 题目大意: 让你用1*2规格的地毯去铺4*n规格的地面,告诉你n,问有多少种不同的方案使得地面恰好被铺满且地毯不重叠.答案 ...