分布式局部聚类系数算法(MapReduce/Hadoop)

19

我已经实现了基于局部聚类系数算法的MapReduce范例。然而,在处理更大的数据集或特定数据集(节点平均度较高)时,我遇到了严重的问题。我尝试调整我的Hadoop平台和代码,但结果令人不满意(至少可以这么说)。现在我将注意力转向实际改变/改进算法。以下是我的当前算法(伪代码):

foreach(Node in Graph) {
  //Job1
  /* Transform edge-based input dataset to node-based dataset */

  //Job2
  map() {
   emit(this.Node, this.Node.neighbours) //emit myself data to all my neighbours
   emit(this.Node, this.Node) //emit myself to myself
  }

  reduce() {
    NodeNeighbourhood nodeNeighbourhood;
    while(values.hasNext) {
      if(myself)
        this.nodeNeighbourhood.setCentralNode(values.next) //store myself data
      else
        this.nodeNeighbourhood.addNeighbour(values.next)  //store neighbour data
    }

    emit(null, this.nodeNeighbourhood)
  }

  //Job3
  map() {
    float lcc = calculateLocalCC(this.nodeNeighbourhood)
    emit(0, lcc) //emit all lcc to specific key, combiners are used
  }

  reduce() {
    float combinedLCC;
    int numberOfNodes;
    while(values.hasNext) {
      combinedLCC += values.next;
    }

    emit(null, combinedLCC/numberOfNodes); // store graph average local clustering coefficient
  }
}

关于代码的更多细节,对于有向图,邻居数据仅限于节点ID和OUT边缘目标ID(以减少数据大小),对于无向图,它也是节点ID和边缘目标ID。排序和合并缓冲区增加到1.5 Gb,合并流为80。

可以清楚地看到,Job2是整个算法的实际问题。它生成了大量数据,必须进行排序/复制/合并。这基本上杀死了我的算法性能,特别是对于某些数据集。有人能指导我如何改进算法吗(我考虑创建一个迭代的Job2,每次迭代只“处理” N中的M个节点,直到处理完每个节点,但我已经放弃了这个想法)。我认为Job2的映射输出应该减少,以避免昂贵的排序/合并过程,这会影响性能。

我还为Giraph平台实现了相同的算法(3个作业,相同的“通信”模式,也存在“Job2”问题)。但是,Giraph是一种内存中的平台,对于相同的“有问题”的数据集而言,该算法会出现OutOfMemoryException。

对于任何评论、意见或指南,我将不胜感激。


更新

我将会“彻底”改变算法。我发现了这篇文章:Counting Triangles

一旦代码实现,我将在此处发布我的意见和更详细的代码(如果这种方法成功的话)。


更新_2

最终,我已经将NodeIterator++算法“修改”以适应我的需求(Yahoo论文可通过文章中的链接获得)。不幸的是,虽然我可以看到性能有所提高,但最终结果并不像我希望的那样好。我得出的结论是,对于这些特定数据集来说,可用于我的集群资源太小,无法使LCC计算成为可能。因此问题仍然存在,或者说它正在发展。有人知道是否存在有效的分布式/顺序算法,可用于计算具有有限资源的LCC或三角形吗?(我并不是说NodeIterator++算法不好,我只是简单地说明我可用的资源不足够)。


2
只是瞎猜而已...你尝试过mahout的聚类作业吗? - Hari Menon
你能修复它吗?Job2的reduce()方法会发出什么? - Hari Menon
不幸的是,mahout的LocalClusteringCoefficientJob并不是我正在寻找的(仅适用于无向图和其他一些问题)。Job2 reduce()会发出NodeNeighbourhood,其中包含中心节点数据和“受限”邻居数据。 - alien01
1
我只能使用Hadoop和Giraph(项目要求)。集群有20个工作节点(+主节点,+3个推测节点),每个节点有8个核心,24GB RAM。数据集不大,只有91MB(过滤后的最大连通组件WikiTalk,可以在SNAP存储库中找到[http://snap.stanford.edu/data/wiki-Talk.html])。但是有“几个”顶点高度相连,因此存在问题。尽管我仍然无法相信我不能在合理的时间内处理它。只是为了展示问题的“规模”。我已经使用Neo4J运行了相同计算(LCC),用于一些大小类似的数据集。平均时间为40-80秒。而WikiTalk需要约10小时。 - alien01
这不是Hadoop,但可能会很有趣。graph-tool local clustering implementation 并行运行(虽然是共享内存OpenMP),我不确定它的实现方式,但我已经尝试过了,即使处理非常大的图形数据,也非常快速。 - jdehesa
显示剩余5条评论
1个回答

1
在论文“基于MPI的MapReduce大规模图算法中的三角计数实现”,作者对MapReduce实现三角计数算法进行了详细描述。该论文可以在这里找到:http://www.sciencedirect.com/science/article/pii/S0167819111000172,但是您可能需要一个帐户才能访问该论文。(我在一所已经为订阅付费的大学系统上,因此我不知道我只能访问哪些内容。)作者可能已经在个人网站上发布了论文草稿。

你可以使用另一种方法来计算三角形-除非你的图比较密集,否则可能不太有效。首先,构建你的图的邻接矩阵A。然后计算A^3 (你可以很容易地并行计算矩阵乘法)。然后,求出A^3的(i,i)条目之和,并将答案除以6。这将给出你三角形的数量,因为A^k的i,j条目计算从i到j的长度为k的路径数,由于我们只看长度为3的路径,所以任何在3步后从i开始并以i结束的路径都是一个三角形...超过计数因子6。如果你的图是稀疏的,这主要是不那么有效率,因为矩阵的大小将比边列表的大小大得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接