在合理的时间内查找两个大数据集中的公共元素

时间:2018-04-19 08:58:49

标签: algorithm apache-spark bigdata

我有两个Spark数据帧DFa和DFb,它们具有相同的架构,(' country',' id',' price',' name& #39)。

  • DFa有大约6.1亿行,
  • DFb有3000毫升的行。

现在我想找到DFa和DFb中具有相同id的所有行,其中id看起来像" A6195A55-ACB4-48DD-9E57-5EAF6A056C80"。

它是一个SQL内部联接,但是当我运行Spark SQL内部联接时,一个任务被杀死,因为容器使用了太多内存并导致Java堆内存错误。而我的集群资源有限,调整YARN和Spark配置不是一种可行的方法。

还有其他解决办法吗?如果运行时间可以接受,也不接受使用火花解决方案。

更一般地说,当在两个非常大的数据集中找到共同元素时,任何人都可以提供一些算法和解决方案。

2 个答案:

答案 0 :(得分:0)

首先计算你的id的64位哈希值。哈希上的比较将比字符串ID快得多。

我的基本想法是:

  • 从DFa构建哈希表。
  • 在计算DFb的哈希值时,可以在表格中进行查找。如果那里什么也没有,那么删除条目(不匹配)。如果你得到一个命中比较实际ID,以确保你没有得到误报。

复杂性为O(N)。不知道你期望多少重叠,这是你可以做的最好的事情,因为你可能必须输出所有内容,因为它们都匹配。

天真的实现会为表使用大约6GB的ram(假设占用率为80%,并且使用平面哈希表),但是你可以做得更好。 由于我们已经有哈希,我们只需要知道它是否存在。因此,您只需要一位来标记可以减少内存使用量的内容(每个条目需要减少64倍的内存,但是您需要降低占用率)。但是,这不是一个常见的数据结构,因此您需要实现它。

但是有更好的东西,甚至更紧凑的东西。这被称为布隆过滤器。这将引入更多的误报,但我们不得不仔细检查,因为我们不相信哈希,所以它并不是一个很大的缺点。最好的部分是你应该能够找到已有的库。

所以一起看起来像这样:

  • 从DFa计算哈希并构建一个布隆过滤器。
  • 从DFb计算哈希值并检查布隆过滤器。如果您在DFa中找到匹配项查找ID,以确保它与实际匹配并将其添加到结果中。

答案 1 :(得分:0)

这是任何大数据环境中的典型用例。您可以使用Map-Side连接来缓存向所有执行程序广播的较小的表。

您可以在此处详细了解广播加入

Broadcast-Joins