我在 JUnit 中进行了一些测试,我需要检查两个 Spark RDD 的相等性。
我想到的一种方式是这样的:
JavaRDD<SomeClass> expResult = ...;
JavaRDD<SomeClass> result = ...;
assertEquals(expResult.collect(), result.collect());
还有比这更好的方法吗?
最佳答案
如果预期结果相当小,最好收集
RDD 数据并在本地进行比较(就像您编写的那样)。
当需要在测试中使用足够大的数据集时,几乎没有其他可能性:
免责声明:我对 Spark Java API 不够熟悉,所以我将在 Scala 中编写更多示例代码。我希望这不会成为问题,因为它可能会用 Java 重写或转换成几个从 Java 代码调用的实用函数。
方法 1:将 RDD 压缩在一起并逐项比较
此方法仅在 RDD 中元素的顺序明确定义(即 RDD 已排序)时可用。
val diff = expResult
.zip(result)
.collect { case (a, b) if a != b => a -> b }
.take(100)
diff
数组最多包含 100 个差分对。如果 RDD 足够大,并且您想从本地获取 diff
中的所有项目,则可以使用 toLocalIterator
方法。最好不要使用 collect
方法,因为你可能会运行 OOM。
这种方法可能是最快的,因为它不需要 shuffle,但只有在 RDD 中的分区顺序和分区中的项目顺序明确定义时才可能使用它。
方法2:联合分组RDD
此方法可用于测试 result
RDD 是否包含没有任何特定顺序的指定(可能是非唯一的)值
val diff = expResult.map(_ -> 1)
.cogroup(result.map(_ -> 1))
.collect { case (a, (i1, i2)) if i1.sum != i2.sum => a -> (i1.sum - i2.sum) }
.take(100)
diff
数组将包含不同的值以及金额之间的差异。
例如:
- 如果
expResult
包含某个值的单个实例,而result
不包含该值,则数字将为+1
;< - 如果
result
包含另一个值的 3 个实例,而expResult
只有 1 个,则数字将为-2
。
此方法将比其他选项(即 RDD 彼此相减)更快,因为它只需要一次洗牌。
关于java - 检查 RDD 的相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27213742/