多个对象列表:如何合并删除重复项

时间:2019-06-06 09:57:26

标签: c++ algorithm duplicates

这个问题很简单,我找到了一些解决方法,但是由于问题的严重性,我需要更具体的帮助。情况如下:

  • 我有几个(假设是20个)c ++对象(都是相同类型)的集合
  • 每个馆藏包含数亿个条目
  • 同一条目可能出现在20个收藏中的一个以上
  • 每个集合由几千个文件组成,每个文件约4GB。每个集合约为50TB,集合的总大小约为1PB
  • 可用的CPU资源:数千个节点(每个节点具有2GB RAM和一个合理的新CPU)。它们都可以异步运行,一个接一个地访问集合的所有文件
  • 可用的磁盘资源:我无法保存所有集合的完整第二份副本(我没有可用的另一个PB磁盘),但是我可以减小每个条目的大小,只保留相关信息。所有集合的最终缩减大小将小于100TB,这没关系。

我想做的是合并20个集合以得到一个集合,其中所有条目都删除所有重复项。进入的总人数约为50亿,并且重复事件的发生率很少(假设为3-5%)。

另一个重要的信息是(全部20个原始集合)的总大小超过1PB,因此处理整个集合确实是一项繁重的任务。

最后:在合并结束时(即,当所有重复项都被删除时),最终集合必须处理几次...因此 合并的输出将用作进一步处理步骤的输入。

这里是一个例子:

Collection1
------------------------------------------
|        | n1 | n2 | n3 | value1...
------------------------------------------
entry0:  | 23 | 11 | 34 | ....  
entry1:  | 43 | 12 | 24 | ....  
entry2:  | 71 | 51 | 91 | ....  
...

Collection2
------------------------------------------
|        | n1 | n2 | n3 | value1...
------------------------------------------
entry0:  | 71 | 51 | 91 | ....  
entry1:  | 73 | 81 | 23 | ....  
entry2:  | 53 | 22 | 84 | ....  
...

如您所见,有3个整数用于区分每个条目(n1,n2和n3),并且collection1中的entry2与collection2中的entry0具有相同的3个整数。后者是前者的重复...合并这两个集合将得到一个包含5个条目的单个集合(已删除了entry0

不对集合进行排序,每个集合由成千上万个文件组成(典型文件大小为4GB,单个集合为TB的十分之一)

关于哪种方法最好的建议?

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

我希望可以订购您的物品? o1 <= o2 <= oN ... 将一个集合加载到内存中并对其进行排序。 将其保存到磁盘。 获取下一个收藏。 解决。 合并磁盘上的两个集合,然后删除第一个集合。 获取下一个收藏...

答案 1 :(得分:0)

鉴于网络的速度和可用节点的数量,这是一种可以继续进行的方法。

您总共有大约5G条目和20个集合。因此,每个集合平均有2.5亿个条目。集合之间的重复条目大约为3-5%(7-12M个条目)。现在,由于您有20个集合分散在数千个节点上,因此每个集合很可能散布在多个节点上。

这是您可以执行的一般步骤。

  1. 对于每个集合,在选定的节点上创建一个数据库,您将在其中存储集合的所有条目ID。该数据库的大小约为几GB。

  2. 在每个节点上,运行一个扫描该节点上所有文件的过程,并将条目ID添加到集合数据库中。

  3. 在单个节点上,运行一个从所有集合数据库读取并查找重复项的过程。在两个集合中发现重复项时,请从两个集合之一中删除条目ID。

  4. 在每个节点上运行一个进程,以从该节点上的文件中删除其ID不在其收集数据库中的所有条目。

最后,所有重复项都被消除了,您还将获得20个数据库,其中包含每个集合中所有条目的ID。