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 ...
随机推荐
- C++ code:判断字符串相等
如果两个字符串中0和1的个数分别相等,则称该对字符串为相等. 方法一: 由于string类对于读取文件中子串以及比较都很方便,所以,用string类的对象来逐对存放字串,然后将字串分别排序后对其进行比 ...
- Java中加密算法介绍及其实现
1.Base64编码算法 Base64简介 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法.可查看RFC2045-RF ...
- String对象的常用属性和方法
属性 描述 length 在大多数情况下返回字符串中的字符数 方法 描述 toUpperCase() 将字符串修改为大写字母 toLowerCase() 将字符串修改为小写字母 charAt() 以索 ...
- setting.xml配置文件
在此,简单的说下. setting.xml 和 pom.xml这两各配置文件,到此是怎样? setting.xml setting.xml,这个配文件,是全局的. 比如你的是构建,web项目.我的是 ...
- iOS 技术篇:如何处理多个网络请求的先后(依赖)关系
在开发过程中,不知你有没有碰到过在一个页面 用到了多个网络请求,而且根据业务需求,需要有次序的执行A B C 网络请求? 你可能会想到,我在A的请求成功回调里去处理B,在B的回调里去请求C,但你后来会 ...
- Xamarin Android组件篇教程RecylerView动画组件RecylerViewAnimators(1)
Xamarin Android组件篇教程RecylerView动画组件RecylerViewAnimators(1) RecyclerView是比ListView和GridView更为强大的布局视图, ...
- iOS html5使用缓存并及时更新方案总结
最近一段时间研究了一下H5在iOS移动端表现时使用缓存并可及时更新方案,总结如下: 一.使用Webview自带缓存机制 当我们使用webview加载html资源时的,本质上就是一个向服务器索取资源的h ...
- nowcoder提高组2题解
T1 化一下试子就ok code #include<cstdio> #include<algorithm> inline long long read() { long lon ...
- Codeforces.788C.The Great Mixing(bitset DP / BFS)
题目链接 \(Description\) 有k种饮料,浓度Ai给出,求用最少的体积配成n/1000浓度的饮料. \(Solution\) 根据题意有方程 (A1x1+A2x2+...+Anxn)/[( ...
- 洛谷.3391.[模板]文艺平衡树(Splay)
题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...