考虑在spark中有2个表或表引用要比较,例如以确保您的备份正常工作。是否有可能在远程执行该操作?因为使用collect()
将所有数据复制到R中没有用。
library(sparklyr)
library(dplyr)
library(DBI)
##### create spark connection here
# sc <- spark_connect(<yourcodehere>)
spark_connection(sc)
spark_context(sc)
trees1_tbl <- sdf_copy_to(sc, trees, "trees1")
trees2_tbl <- sdf_copy_to(sc, trees, "trees2")
identical(trees1_tbl, trees2_tbl) # FALSE
identical(collect(trees1_tbl), collect(trees2_tbl)) # TRUE
setequal(trees1_tbl, trees2_tbl) # FALSE
setequal(collect(trees1_tbl), (trees2_tbl)) # TRUE
spark_disconnect(sc)
如果可以直接使用dplyr::setequal()
,那就太好了。
答案 0 :(得分:1)
这是行不通的。这里要记住的要点是,Spark DataFrames
*不是数据容器。一旦执行管道,就会有转换的描述,这些转换将应用于数据。这意味着,每次评估数据时,结果可能会有所不同。您在这里可以问的唯一有意义的问题是,DataFrames
是否都描述了相同的执行计划,这显然对您的情况没有用。
那么如何比较数据?这里真的没有通用答案。
测试
如果它是单元测试的一部分,则要收集数据并比较本地对象是正确的方法(尽管请记住,使用集合可能会遗漏一些细微但常见的问题)。
生产
外部单元测试,您可以尝试检查是否
然而,这是非常昂贵的,并且如果可行的话可能会大大增加该过程的成本。因此,在实践中,您可能更喜欢不提供严格保证但具有更好性能指标的方法。这些将取决于输入和输出源以及故障模型(例如,基于文件的源比使用数据库或消息队列的源更可靠)。
在最简单的情况下,您可以使用Spark Web UI手动检查基本不变式,例如读取和写入的行数。对于更高级的监视,您可以实现自己的Spark侦听器(例如检查Spark: how to get the number of written rows?,查询侦听器或累加器,但是所有这些组件都不会在sparklyr
中公开,并且需要编写本机代码(Scala或Java) )代码。
*我在这里指的是Spark,但是将dplyr
与数据库后端一起使用并没有什么不同。
答案 1 :(得分:1)
我写了一个示例,说明我认为您可以做到。基本上,您只需要对两个表进行合并,然后在合并结果中应用distinct()。在distinct()之后,只需将结果数据帧的行数与初始行数进行比较。
>>> rdd = spark.sparkContext.parallelize([("test","test1")])
>>> rdd.collect()
[('test', 'test1')]
>>> df1 = spark.createDataFrame(rdd).toDF("col1","col2")
>>> df1.show()
+----+-----+
|col1| col2|
+----+-----+
|test|test1|
+----+-----+
>>> df2 = spark.createDataFrame(rdd).toDF("col1","col2")
>>> df2.show()
+----+-----+
|col1| col2|
+----+-----+
|test|test1|
+----+-----+
>>> df3 = df1.union(df2)
>>> df3.show()
+----+-----+
|col1| col2|
+----+-----+
|test|test1|
|test|test1|
+----+-----+
>>> df3.distinct().show()
+----+-----+
|col1| col2|
+----+-----+
|test|test1|
+----+-----+
>>> df1.count()
1
>>> df3.distinct().count()
1
答案 2 :(得分:0)
感谢@ Cosmin的提示!
首先使用setdiff()
,它有一种tbl_lazy
提供的dplyr
对象的方法(与setequal
不同),对行进行计数并将其与0进行比较。
trees1_tbl %>% setdiff(trees2_tbl) %>% sdf_nrow() == 0
## TRUE
如果来自TRUE
的所有数据都包含在trees1_tbl
中,将导致trees2_tbl
。
如果它们不同,则可以省略== 0
以获得trees2_tbl
中缺少的行数。