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文件每天更新一份)的更多相关文章

  1. jdk8系列三、jdk8之stream原理及流创建、排序、转换等处理

    一.为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX ...

  2. [三]java8 函数式编程Stream 概念深入理解 Stream 运行原理 Stream设计思路

    Stream的概念定义   官方文档是永远的圣经~     表格内容来自https://docs.oracle.com/javase/8/docs/api/   Package java.util.s ...

  3. 微信小程序把玩(三十七)location API

    原文:微信小程序把玩(三十七)location API location API也就分这里分两种wx.getLocation(object)获取当前位置和wx.openLocation(object) ...

  4. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...

  5. NeHe OpenGL教程 第三十七课:卡通映射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. spark三种连接Join

    本文主要介绍spark join相关操作. 讲述spark连接相关的三个方法join,left-outer-join,right-outer-join,在这之前,我们用hiveSQL先跑出了结果以方便 ...

  7. Java进阶(三十七)java 自动装箱与拆箱

    Java进阶(三十七)java 自动装箱与拆箱 前言 这个是jdk1.5以后才引入的新的内容.java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装称为装箱,解包装称为 ...

  8. Gradle 1.12用户指南翻译——第三十七章. OSGi 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  9. SQL注入之Sqli-labs系列第三十六关(基于宽字符逃逸GET注入)和三十七关(基于宽字节逃逸的POST注入)

    0X1 查看源码 function check_quotes($string) { $string= mysql_real_escape_string($string); return $string ...

随机推荐

  1. three.js 相机camera位置属性设置详解

    开始很懵逼,完全不能理解,有个position,还要up和lookAt干嘛. [黑人问号脸❓❓❓] 既然是位置属性不明白,那默认其它属性都懂了. 上坐标轴: 先来第一个position属性,可以设置x ...

  2. php中foreach()跳出循环或者终止循环的实现方法

    $arr = array('a','b','c','d','e'); $html = ''; foreach($arr as $key => $value){ if($value=='b'){ ...

  3. SPLAY,LCT学习笔记(一)

    写了两周数据结构,感觉要死掉了,赶紧总结一下,要不都没学明白. SPLAY专题: 例:NOI2005 维修数列 典型的SPLAY问题,而且综合了SPLAY常见的所有操作,特别适合新手入门学习(比如我这 ...

  4. Oracle GoldenGate常用配置端口

    1 简介 Oracle Golden Gate软件是一种基于日志的结构化数据复制备份软件,它通过解析源数据库在线日志或归档日志获得数据的增量变化,再将这些变化应用到目标数据库,从而实现源数据库与目标数 ...

  5. 使用Maven进行多模块拆分

    模块拆分是Maven经常使用的功能,简单梳理一下如何使用Maven进行多模块拆分, 只做归纳总结,网上资料很多,不再一步一步实际创建和部署. 建立Maven多模块项目 一个简单的Java Web项目, ...

  6. 记录weiye项目上线遇到的一些问题

    1.使用vpn访问客户内网 参考:http://jingyan.baidu.com/article/a3f121e4f9903cfc9052bb0b.html 2.设置使用ip地址直接访问项目(之后可 ...

  7. hdu1873 看病要排队【优先队列】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1873 看病要排队 Time Limit: 3000/1000 MS (Java/Others)     ...

  8. 使用OutputStream向屏幕上输出内容

    使用OutputStream向屏幕上输出内容 /** * 使用OutputStream向屏幕上输出内容 */ import java.io.*; class hello { public static ...

  9. zip&ftp命令

    zip: C:\Users\IBM_ADMIN>zip -09r Oracle.zip ./Oracle/* C:\Users\IBM_ADMIN>ftp ftp> open adm ...

  10. C# GUID生成

    System.Guid.NewGuid().ToString()