Algorithm Perl处理一万亿条记录 寻找关于Perl中一个简单的方法来比较文本文件的建议或洞察力。p>

Algorithm Perl处理一万亿条记录 寻找关于Perl中一个简单的方法来比较文本文件的建议或洞察力。p>,algorithm,perl,Algorithm,Perl,假设有90000个文本文件,它们的结构都很相似,比如说它们有一个共同的主题,每个主题中都有少量的唯一数据 我的逻辑是简单地循环文件(为了简单起见分成1000行),然后循环文件的#。。。90000-然后再次循环浏览90000个文件以相互比较。这实际上变成了无数条生产线或流程的无止境循环 现在,这里的强制步骤是“删除”除我们正在处理的文件之外的任何文件中的任何行。最终目标是将所有文件清理为整个集合中唯一的内容,即使这意味着某些文件最终为空 我说的是文件,但这可能是数据库中的行,也可能是数组中的元素。

假设有90000个文本文件,它们的结构都很相似,比如说它们有一个共同的主题,每个主题中都有少量的唯一数据

我的逻辑是简单地循环文件(为了简单起见分成1000行),然后循环文件的#。。。90000-然后再次循环浏览90000个文件以相互比较。这实际上变成了无数条生产线或流程的无止境循环

现在,这里的强制步骤是“删除”除我们正在处理的文件之外的任何文件中的任何行。最终目标是将所有文件清理为整个集合中唯一的内容,即使这意味着某些文件最终为空

我说的是文件,但这可能是数据库中的行,也可能是数组中的元素。到目前为止,最快的解决方案是将所有文件加载到mysql中,然后运行 更新表集合列=替换(列,查找,替换);在使用mysql时,还尝试了Parallel::ForkManager

最慢的方法实际上会耗尽我的32 GB内存,这意味着将所有90k文件加载到一个数组中。90k文件根本不起作用,像1000个这样的小批量也可以,但与其他89000个文件相比就不起作用了

服务器规格(如有帮助):单四核E3-1240 4芯x 3.4Ghz w/HT 32GB DDR3 ECC RAM 1600MHz 1x256SSD


那么工程师如何解决这个问题呢?我只是一个PERL黑客…

用文件名(可能还有行号)标记每一行,并使用。然后,您可以按顺序读取已排序的记录,并只向结果文件中写入一行唯一的内容。

用文件名(可能还有行号)标记每一行,然后使用对所有行进行排序。然后,您可以按顺序读取已排序的记录,并只向结果文件写入一行唯一的内容。

如果您可以处理任意小的错误,Bloom筛选器非常适合此操作

引用维基百科:“Bloom筛选器是一种节省空间的概率数据结构,用于测试元素是否为集合的成员。可能存在误报匹配,但不存在误报;即查询返回“可能在集合中”或“肯定不在集合中”

本质上,您将使用k个散列将每行散列到位数组上的k个点。每次遇到新行时,如果k个散列索引中至少有一个具有“0”位,则可以保证没有看到它。您可以阅读Bloom过滤器,了解如何调整数组大小,并选择k使误报任意小


然后检查文件,删除获得正匹配的行,或将负匹配行复制到新文件中。

如果可以处理任意小错误,Bloom筛选器非常适合此操作

引用维基百科:“Bloom筛选器是一种节省空间的概率数据结构,用于测试元素是否为集合的成员。可能存在误报匹配,但不存在误报;即查询返回“可能在集合中”或“肯定不在集合中”

本质上,您将使用k个散列将每行散列到位数组上的k个点。每次遇到新行时,如果k个散列索引中至少有一个具有“0”位,则可以保证没有看到它。您可以阅读Bloom过滤器,了解如何调整数组大小,并选择k使误报任意小


然后浏览文件,删除获得正匹配的行,或将负匹配行复制到新文件中。

使用外部合并排序算法对项目进行排序,并在合并阶段删除重复项

实际上,只需使用
-u
标志调用
sort
命令,就可以有效地实现这一点。来自Perl:

system "sort -u @files >output";

您的
sort
命令可以提供几个可调整的参数来提高其性能。例如,并行进程的数量或它可以分配的内存量。

使用外部合并排序算法对项目进行排序,并在合并阶段删除重复项

实际上,只需使用
-u
标志调用
sort
命令,就可以有效地实现这一点。来自Perl:

system "sort -u @files >output";

您的
sort
命令可以提供几个可调整的参数来提高其性能。例如,并行进程的数量或它可以分配的内存量。

您可能想了解
rsync
如何使用滚动校验和来比较源文件和目标文件,以便只发送已更改的部分文件。您可以将其应用到任务的算法中。这是一个好主意。。。调查一下。我还忘了补充一点,从理论上讲,文件会随着时间的推移而变小,所以速度应该会加快。这叫做滚动哈希,还有一个perl模块,我将在这里测试它是否有用。比较的目的是什么?是否要查找相同的文件?我要“清除”所有文件中的所有重复内容,使每个文件只保留在其他文件中找不到的唯一数据(行)。您可能想了解
rsync
如何使用滚动校验和来比较源文件和目标文件,以便只发送已更改的部分文件。您可以将其应用到任务的算法中。这是一个好主意。。。调查一下。我还忘了补充一点,从理论上讲,文件会随着时间的推移而变小,所以速度应该会加快。这叫做滚动哈希,还有一个perl模块,我将在这里测试它是否有用。比较的目的是什么?是否要查找相同的文件?我要“清除”所有文件中的所有重复内容,使每个文件只包含其他文件中找不到的唯一数据(行)。此文件在我的90000测试中运行良好。基本上需要20分钟来构建阵列,