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接口自动化测试二:常用操作
url = '接口地址' r = requests.get(url) # 发送get请求 print(r.status_code) ...
- 《Kafka技术内幕》学习笔记
第一章 Kafka入门 1.1 Kafka流式数据平台 Kafka作为流式数据平台的特点: 消息系统:两种消息模型:队列和发布订阅. 队列模型:将处理工作平均分给消费组中的消费者成员. 发布订阅模型: ...
- C# event关键字
直接使用委托的写法,如下: using System; namespace ConsoleAppTest { class Program { class Test { static void Main ...
- POJ 3190 Stall Reservations【贪心】
POJ 3190 题意: 一些奶牛要在指定的时间内挤牛奶,而一个机器只能同时对一个奶牛工作.给你每头奶牛的指定时间的区间(闭区间),问你最小需要多少机器.思路:先按奶牛要求的时间起始点进行从小到大排序 ...
- 【BZOJ4504】K个串
题解: 这题跟超级noi钢琴思路大致相同 不同之处在于如何寻找最大值 这道题里出现了每个数都只能被算一次这个限制 我们考虑一下如果还要使用主席树和前缀和该怎么做 我们每次操作一个数时,可以让这个数上一 ...
- maven添加插件,与maven打包
1.编译插件 添加编译器插件来告诉 Maven 使用哪个 JDK 版本是用来编译项目. 2.pom <plugin> <groupId>org.apache.maven.plu ...
- 018 spark on yarn (Job history)的配置,主要是yarn处跳转到历史聚合页面
一:目标 1.目标 在yarn的8080页面可以跳转到spark的日志18080页面. 因为在运行spark之后,看对应的job的日志,这样直接连接,更合理直接. 2.总结 在后面可以看到,其实不需要 ...
- 008 Spark中standalone模式的HA(了解,知道怎么配置即可)
standalone也存在单节点问题,这里主要是配置两个master. 1.官网 2.具体的配置 3.配置方式一(不是太理想) 这种知识基于未来可以重启,但是不能在宕机的时候提供服务. 方式一:Sin ...
- java连接数据库(jdbc)调用配置文件
各种语言都有自己所支持的配置文件,后缀名“.properties”结尾的就是其中之一. 在java连接数据库时,采取读取配置文件的方式,来获取数据库连接. 新建jdbc.properties文件,内容 ...
- linux学习之使用fdisk命令进行磁盘分区(八)
linux下使用fdisk命令进行磁盘分区 目录 分区类型 分区方法表示 文件系统 fdisk命令分区过程 分区类型 主分区:总共最多只能分四个 扩展分区:只能有一个,也算作主分区的一种,也就是说主分 ...