在Appengine上使用mapreduce重复200万条记录的糟糕表现

cha*_*g30 5 java google-app-engine hadoop mapreduce deduplication

我有大约200万条记录,每条记录有大约4个字符串字段,每个字段都需要检查重复项.更具体地说,我将名称,电话,地址和父名称作为字段,我必须使用所有这些字段检查重复数据删除与其余数据.产生的唯一记录需要记录到db中.

我已经能够实现mapreduce,迭代所有记录.任务率设置为100/s,桶大小设置为100.启用计费.

目前,一切正常,但性能非常缓慢.我已经能够在6小时内完成10,000个记录的测试数据集中的1000个记录重复数据删除处理.

java中的当前设计是:

  1. 在每个地图迭代中,我将当前记录与先前记录进行比较
  2. 以前的记录是db中的单个记录,其作用类似于全局变量,我在每个映射迭代中用另一个先前记录覆盖
  3. 使用算法进行比较,并将结果作为新实体写入db
  4. 在一个Mapreduce作业结束时,我以编程方式创建另一个作业
  5. 先前的记录变量有助于将作业与下一个候选记录与其余数据进行比较

我准备增加任何数量的GAE资源,以便在最短的时间内实现这一目标.

我的问题是:

  1. 重复数据删除(检查重复项)的准确性是否会因并行作业/任务而受到影响?
  2. 如何改进这种设计?
  3. 这将扩大到2000万条记录
  4. 什么是在地图迭代期间读取/写入变量(不仅仅是计数器)的最快方法,可以在一个mapreduce作业中使用.

欢迎自由职业者为此提供帮助.

谢谢你的帮助.

mik*_*kea 3

我看到有两种方法可以解决这个问题:

  1. (如果您只需要执行一次)AppEngine 会为实体中的每个属性创建一个属性索引(除非您要求它不要这样做)。创建一个后端,使用游标批量运行查询“SELECT * FROM ORDER BY”,确定重复的属性并修复/删除它们。您也许能够并行化它,但是在分片边界上这很棘手,并且您可能必须自己编写所有代码。

  2. 您可以使用映射器框架来减慢速度,但并行运行。这种方法还允许您在插入时有效地删除重复数据。引入一个新实体来保存唯一的属性值。说“唯一电话号码”。该实体应持有电话号码作为密钥以及对具有该电话号码的实体的引用。现在运行地图并查找 UniquePhoneNumber。如果找到并且其引用有效,请删除重复项。如果没有,请使用正确的参考创建一个新的。这样,如果需要,甚至可以重新指向另一个引用。确保您在单个事务中读取 UniquePhoneNumber 并创建一个新电话号码/更新一个新电话号码。否则将不会检测到重复项。