问题描述:DataFrame的join结果不正确,dataframeA(6000无重复条数据) join dataframeB(220条无重复数据,由dataframeA转化而来,key值均源于dataframeA) 只有200条数据,丢了20条

问题验证:

1,查询丢的20条数据,均无异常,不存在Null,数据不存在空格

2,重新运行算法,丢18条数据,证明丢数据存在一定随机性

3,简化问题到最简模式,代码如下:

    val xxx1= phySiteEvaluationPhySiteKey.select("physitekey").distinct()
val xxx2= physitefinal.select("physitekey").distinct()
val xxx3 = xxx1.join(xxx2, Seq("physitekey")) val rdd1=xxx1.rdd.map(r=>r.getAs[String]("physitekey")).map(r=>(r,r))
val rdd2 =xxx2.rdd.map(r=>r.getAs[String]("physitekey")).map(r=>(r,r))
val rdd3=rdd1.join(rdd2) log.info(s"rdd3=${rdd3.count()}")
log.info(s"xxx3==${xxx3.count()}")

xxx3和rdd3的结果居然不相等!!违背了spark常识

问题分析:

1,据spark原理可知,DataFrame的底层实现就是RDD,具体实现在Catalyst包类,需要DataFrame=>未解析的逻辑执行计划=>解析逻辑计划=>优化逻辑执行计划=>物理执行计划=>RDD执行

也就是说xxx3的执行计划生成出的RDD执行方案与RDD3结果不一致,因此在这里我打印了xxx3的执行计划,期望有所发现

    xxx1.join(xxx2, Seq("physitekey")).explain()

执行计划长达1000多行,涉及内部实现因项目保密需要无法展示。

2,执行计划超长是因为phySiteEvaluationPhySiteKey、physitefinal均为迭代计算结果,不是直接来源于输入表

3,依据执行计划,我猜测Spark在逻辑计划优化的时候出错,导致结果不符合预期

4,验证方案:为xxx1、xxx2的取值加上checkpoint,斩断血缘依赖,重新查看执行计划是否符合预期

    val xxx1= phySiteEvaluationPhySiteKey.select("physitekey").distinct().checkpoint()
val xxx2= physitefinal.select("physitekey").distinct().checkpoint()
xxx1.join(xxx2, Seq("physitekey")).explain()
val xxx3 = xxx1.join(xxx2, Seq("physitekey")) val rdd1=xxx1.rdd.map(r=>r.getAs[String]("physitekey")).map(r=>(r,r))
val rdd2 =xxx2.rdd.map(r=>r.getAs[String]("physitekey")).map(r=>(r,r))
val rdd3=rdd1.join(rdd2) log.info(s"rdd3=${rdd3.count()}")
log.info(s"xxx3==${xxx3.count()}")

结果执行计划如下:

== Physical Plan ==
*Project [physitekey#1648]
+- *SortMergeJoin [physitekey#1648], [physitekey#43875], Inner
:- *Sort [physitekey#1648 ASC NULLS FIRST], false, 0
: +- Exchange(coordinator id: 1135069612) hashpartitioning(physitekey#1648, 200), coordinator[target post-shuffle partition size: 67108864]
: +- *Filter isnotnull(physitekey#1648)
: +- Scan ExistingRDD[physitekey#1648]
+- *Sort [physitekey#43875 ASC NULLS FIRST], false, 0
+- Exchange(coordinator id: 1135069612) hashpartitioning(physitekey#43875, 200), coordinator[target post-shuffle partition size: 67108864]
+- *Filter isnotnull(physitekey#43875)
+- Scan ExistingRDD[physitekey#43875]

没有问题,RDD3与XXX3结果相等,正确了。

确认问题出在Spark中DataFrame在持有超长血缘关系时转化为RDD执行出错,具体错误有机会下次分析,应当是仅在一定特殊情况下才会暴露的BUG

5、问题反思

开源组件也是可能存在BUG的,应当在使用时尽量使用其最常见的用法,列如在本问题中,如果迭代计算之后及时斩断血缘依赖,就不会出现问题

Spark解决SQL和RDDjoin结果不一致问题(工作实录)的更多相关文章

  1. Spark(Hive) SQL数据类型使用详解(Python)

    Spark SQL使用时需要有若干“表”的存在,这些“表”可以来自于Hive,也可以来自“临时表”.如果“表”来自于Hive,它的模式(列名.列类型等)在创建时已经确定,一般情况下我们直接通过Spar ...

  2. Spark(Hive) SQL中UDF的使用(Python)

    相对于使用MapReduce或者Spark Application的方式进行数据分析,使用Hive SQL或Spark SQL能为我们省去不少的代码工作量,而Hive SQL或Spark SQL本身内 ...

  3. Spark(Hive) SQL中UDF的使用(Python)【转】

    相对于使用MapReduce或者Spark Application的方式进行数据分析,使用Hive SQL或Spark SQL能为我们省去不少的代码工作量,而Hive SQL或Spark SQL本身内 ...

  4. windows 系统本地做mysql 主从同步,最后面解决主从同步库名不一致,表结构一致

    原文:windows 系统本地做mysql 主从同步,最后面解决主从同步库名不一致,表结构一致 mysql主从同步的好处以及原理       之前看到很多新闻说某某的服务器奔溃,磁盘碎了,导致数据丢失 ...

  5. Caused by: java.sql.SQLSyntaxErrorException: ORA-00932: 数据类型不一致: 应为 NUMBER, 但却获得 BINARY

    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvo ...

  6. MyBatis(5)——解决属性名与列名不一致的问题

    解决属性名与列名不一致的问题 问题描述: 当实体类的属性与数据库的列名不对应时取不到该列数据 说明:MyBatis会根据查询的列名设值(列名的setter方法),然后以此列名为做查询等操作,在此过程中 ...

  7. WARN deploy.SparkSubmit$$anon$2: Failed to load org.apache.spark.examples.sql.streaming.StructuredNetworkWordCount.

    前言 今天运行Spark Structured Streaming官网的如下 ./bin/run-example org.apache.spark.examples.sql.streaming.Str ...

  8. IBatis.Net使用总结(一)-- IBatis解决SQL注入(#与$的区别)

    IBatis解决SQL注入(#与$的区别) 在IBatis中,我们使用SqlMap进行Sql查询时,需要引用参数,在参数引用中可以使用两种占位符#和$.这两种占位符有什么区别呢? (1):#***#, ...

  9. Spark之SQL解析(源码阅读十)

    如何能更好的运用与监控sparkSQL?或许我们改更深层次的了解它深层次的原理是什么.之前总结的已经写了传统数据库与Spark的sql解析之间的差别.那么我们下来直切主题~ 如今的Spark已经支持多 ...

随机推荐

  1. Python之sqlite3模块

    python自带有sqlite3模块,该模块可以方便我们操作sqlite数据库,下面一起跟随示例了解sqlite3模块的具体用法. import sqlite3 # 连接数据库 connection ...

  2. 剑指 Offer 38. 字符串的排列

    剑指 Offer 38. 字符串的排列 输入一个字符串,打印出该字符串中字符的所有排列. 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素. 示例: 输入:s = "abc" ...

  3. javascript(1)简介

    点击查看代码 ### javascript 1.JavaScript简介 javascript是一种轻量级的脚本语言,可以部署在多种环境,最常见的部署环境就是浏览器, 脚本语言: 它不具备开发操作系统 ...

  4. ysoserial CommonsColletions3分析(1)

    CC3的利用链在JDK8u71版本以后是无法使用的,具体还是由于AnnotationInvocationHandler的readobject进行了改写. 而CC3目前有两条主流的利用链,利用Trans ...

  5. C语言中的符号重载

    摘自<C专家编程>第二章37页                     C语言中符号的重载 符号 意义 static 在函数内部,表示该变量的值在各个调用间一直保持延续性在函数这一级,表示 ...

  6. django 模版-标签-视图-csrf-token-模版继承-HTML过滤器

    """ ******模版****** --定义模版-- **变量** 视图传递给模版的数据 注意1:要遵守标识符规则 语法:{{var(即变量)}} 如果使用的变量不存在 ...

  7. 鸿蒙内核源码分析(GN应用篇) | GN语法及在鸿蒙的使用 | 百篇博客分析OpenHarmony源码 | v60.01

    百篇博客系列篇.本篇为: v60.xx 鸿蒙内核源码分析(gn应用篇) | gn语法及在鸿蒙的使用 | 51.c.h.o 编译构建相关篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙 ...

  8. P5782-[POI2001]和平委员会【2-SAT】

    正题 题目链接:https://www.luogu.com.cn/problem/P5782 题目大意 \(n\)对人,每对之间恰好有一个人出席.\(m\)对仇恨关系表示两个人不能同时出席. 求是否有 ...

  9. P3180-[HAOI2016]地图【圆方树,莫队,分块】

    正题 题目链接:https://www.luogu.com.cn/problem/P3180 题目大意 \(n\)个点\(m\)条边的一个仙人掌,有点权. \(Q\)次询问给出\(op,x,y\),封 ...

  10. 记一次centos挂载ceph存储的坑

    起因 生产有两台服务器,准备用来跑工作流,执行的资源的是放在ceph存储集群中,第一步挂载ceph 执行命令:mount -t ceph xxx:xxx -o name=admin,secret=AQ ...