Hadoop中输入行的成对聚合

Hadoop中输入行的成对聚合,hadoop,Hadoop,一组行驶中的汽车产生轨迹(有序位置序列) 我想计算汽车行驶的距离(路径长度) 在核心,我需要逐行成对地处理所有记录。如果 前一行的车号与当前车号相同,我需要 计算到上一个位置的距离,并将其相加到聚合的距离 价值如果前一行的车辆id与当前行不同 然后我需要输出前一个car_id的聚合,并初始化 当前车辆id的聚合为零 hadoop程序的架构应该是什么样子?有可能吗 归档以下文件: 解决方案(1): (a) 每个映射器计算跟踪的聚合距离(每个物理路径) 块) (b) 如果轨迹被分割,每个映射器都会进

一组行驶中的汽车产生轨迹(有序位置序列)

我想计算汽车行驶的距离(路径长度)

在核心,我需要逐行成对地处理所有记录。如果 前一行的车号与当前车号相同,我需要 计算到上一个位置的距离,并将其相加到聚合的距离 价值如果前一行的车辆id与当前行不同 然后我需要输出前一个car_id的聚合,并初始化 当前车辆id的聚合为零

hadoop程序的架构应该是什么样子?有可能吗 归档以下文件:

解决方案(1):

(a) 每个映射器计算跟踪的聚合距离(每个物理路径) 块)

(b) 如果轨迹被分割,每个映射器都会进一步聚合距离 在多个块和节点之间

备注:此解决方案需要知道我是否在最后一条记录(行)上 在街区的另一边。这些信息有吗

解决方案(2)

(a) 制图员逐行读取数据(不进行计算)并发送 根据车辆id向减速器发送数据

(b) 减速器根据订单id对单个车辆id的数据进行排序, 计算距离并将其聚合

注释:由于映射程序的惰性,网络负载较高

解决方案(3)

(a) 实现一个自定义读卡器来读取定义为完整的逻辑记录 一辆车的痕迹

(b) 每个映射器计算距离和聚合

(c) 实际上不需要reducer,因为一切都是由映射器完成的

注释:主内存成本高,因为整个跟踪需要加载到主内存中 内存(虽然一次只使用两行)。

我会选择解决方案(2),因为它是实现和重用最干净的

您当然希望根据car_id和order_id进行排序,这样您就可以在不将它们全部加载到内存的情况下实时计算距离

您对高网络使用率的担忧是正确的,但是,您可以在组合器中预先聚合距离

那会是什么样子,让我们看一些伪代码:

制图员:

  foreach record:
    emit((car_id, order_id), (x,y))
组合器:

if(prev_order_id + 1 == order_id): // subsequent measures
     // compute distance and emit that as the last possible order
     emit ((car_id, MAX_VALUE), distance(prev, cur)) 
else:
     // send to the reducer, since it is probably crossing block boundaries
     emit((car_id, order_id), (x,y)) 
然后,减速器有两个主要部件:

  • 计算后续度量的总和,就像合并器所做的那样
  • 所有现有总和的总和,标记为订单号=最大值
这已经是您从网络使用POV中所能获得的最大努力

从软件的角度来看,最好使用Spark——三个类文件中的逻辑将是五行而不是100行

关于你的另一个问题:

此解决方案需要知道我是否在最后一条记录(行)上 在街区的另一边。这些信息有吗

Hadoop只保证在读取时不会分割记录,很可能您的记录已经接触到下面的两个不同块。找到答案的方法基本上是重写您的输入格式,使这些信息可供您的映射程序使用,甚至更好-在分割块时考虑您的逻辑

if(prev_order_id + 1 == order_id): // subsequent measures
     // compute distance and emit that as the last possible order
     emit ((car_id, MAX_VALUE), distance(prev, cur)) 
else:
     // send to the reducer, since it is probably crossing block boundaries
     emit((car_id, order_id), (x,y))