最近,我成功地创建了一个自定义顶点类,其中每个顶点都有一个LongWritable id,这个id也是它自己的值。我的Giraph程序在一个小顶点集(100,000个顶点)上成功运行,程序完成并输出预期值。但是,当我将音量增加到3000万个顶点时,程序会在总内存最大化时挂起(每个映射器的堆大小为1.5 GB)。由于我的顶点类只保存一个id和值(8 + 8 = 16字节)以及发出的边(平均8 * 8 * 2 = 128字节),我不明白为什么内存消耗如此之高。从下面的日志消息中,内存最大值为450万个顶点,大小为1363 MB,因此当Giraph运行时,每个顶点占用317个字节。 Giraph中的哪些额外数据结构导致字节/顶点如此之高?
readVertexInputSplit: Loaded 4500000 vertices at 90245.3768041096 vertices/sec 0 edges at 0.0 edges/sec Memory (free/total/max) = 187.52M / 1363.00M / 1365.50M
waitFor: Future result not ready yet java.util.concurrent.FutureTask@5f7bd943
答案 0 :(得分:0)
只需为寻找者提供答案。
尝试更改Giraph保留分区的方式。
如果使用默认值,则开销很大。
请改用org.apache.giraph.partition.ByteArrayPartition
,它可以有效地仅将数据保存为字节数组,而不能以包装形式保存。 Java拥有对象的开销很大,在您的情况下,由于您有许多小对象,这很明显-因此浪费也很高。
此外,通常建议不要运行小型映射器。 最好有几个功能强大的节点(大约10个内核和30-60GB RAM),而不是几十个小型节点。
可能还有其他一些原因,但我不能不详细说明。