昨天下午对HDFS的速度进行了测试,晚上又对Hama的peer间通信通信速度进行了测试。
[转载引用请注明出处:http://blog.csdn.net/bhq2010/article/details/8741647]
和之前的hdfs测试中用的是一样的:http://blog.csdn.net/bhq2010/article/details/8740154
hama安装的是0.6.0版本。
在setup方法中选出一个master task作为主peer
在bsp中写了2个超步,第一个超步读取本地的文件,并将其一部分发送给master
master在第二个超步中接收到其他peer发过来的消息(数据),将其写入本地的文件中。
有一点需要注意,应该设定bspTask个数为集群中节点的个数,这样通常每个节点上会有且仅有一个bsp任务。少了会使得有些节点上没有bsp任务,多了会使得一个节点上的多个bsp任务同时读取一个文件,然后就挂掉了。
测试程序如下:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.io.Text; import org.apache.hama.HamaConfiguration; import org.apache.hama.bsp.BSP; import org.apache.hama.bsp.BSPJob; import org.apache.hama.bsp.BSPJobClient; import org.apache.hama.bsp.BSPPeer; import org.apache.hama.bsp.ClusterStatus; import org.apache.hama.bsp.FileOutputFormat; import org.apache.hama.bsp.NullInputFormat; import org.apache.hama.bsp.TextOutputFormat; import org.apache.hama.bsp.sync.SyncException; public class HamaTest { private static Path TMP_OUTPUT = new Path("/tmp/pi-" + System.currentTimeMillis()); public static class CommunicationTest extends BSP<NullWritable, NullWritable, Text, Text, Text> { public static final Log LOG = LogFactory.getLog(CommunicationTest.class); private String masterTask; @Override public void bsp( BSPPeer<NullWritable, NullWritable, Text, Text, Text> peer) throws IOException, SyncException, InterruptedException { File f = new File("/data/external_links_en.nt"); if (f.exists()) { int i = 0; FileReader fr = new FileReader("/data/external_links_en.nt"); BufferedReader reader = new BufferedReader(fr); String line = null; while ((line = reader.readLine()) != null) { i++; if (i > 661700) { break; } peer.send(masterTask, new Text(line)); } reader.close(); } peer.sync(); if (peer.getPeerName().equals(masterTask)) { Text received; FileWriter fw = new FileWriter("/data/tmpres"); BufferedWriter writer = new BufferedWriter(fw); while ((received = peer.getCurrentMessage()) != null) { writer.write(received.toString() + "\n"); } writer.close(); } peer.sync(); } @Override public void setup( BSPPeer<NullWritable, NullWritable, Text, Text, Text> peer) throws IOException { // Choose one as a master String[] allPeerNames = peer.getAllPeerNames(); int port = 0; for (String peerName : allPeerNames) { if (peerName.split(":")[0].equals("iir455-200")) { if (port == 0 || Integer.parseInt(peerName.split(":")[1]) < port) { port = Integer.parseInt(peerName.split(":")[1]); masterTask = peerName; } } } try { peer.sync(); } catch (SyncException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void cleanup( BSPPeer<NullWritable, NullWritable, Text, Text, Text> peer) throws IOException { } } public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException { HamaConfiguration conf = new HamaConfiguration(); BSPJob bsp = new BSPJob(conf, HamaTest.class); bsp.setJobName("Connection Speed Test"); bsp.setBspClass(CommunicationTest.class); bsp.setInputFormat(NullInputFormat.class); bsp.setOutputKeyClass(Text.class); bsp.setOutputValueClass(Text.class); bsp.setOutputFormat(TextOutputFormat.class); FileOutputFormat.setOutputPath(bsp, TMP_OUTPUT); BSPJobClient jobClient = new BSPJobClient(conf); ClusterStatus cluster = jobClient.getClusterStatus(true); if (args.length > 0) { bsp.setNumBspTask(Integer.parseInt(args[0])); } else { bsp.setNumBspTask(cluster.getMaxTasks()); } long startTime = System.currentTimeMillis(); if (bsp.waitForCompletion(true)) { System.out.println("Job Finished in " + (System.currentTimeMillis() - startTime) / 1000.0 + " seconds"); } } }
如果改成只发前66170行,则用时在20秒左右,可见时间消耗主要在通信上。
Hama的peer之间通信速度和健壮性都不理想:
1、从六个节点向一个节点传410MB的消息居然平均用了110秒,去掉启动任务的大约10秒钟,其平均的传输速度只有4MB/s;
2、非常吃内存,剩余将近3GB的内存,竟然跑一个几百兆通信量的Job就会报内存不足,当然这也可能是Hama配置的问题,睡完觉了再查查文档;
所以还是不要用hama本身的同步通信功能传递大量的数据,它只适合在同步计算过程中发送少量的消息。