日期:2014-05-16  浏览次数:20437 次

hadoop集群启动过程模拟

hadoop启动会进过一个安全模式,安全模式有如下几个特点:

安全模式下namenode收集各个datanode的报告,当数据块达到最小副本数(复制因子)以上时,会被认为是“安全”的 。

在一定比例(可设置)的数据块被确定为“安全”后,再过若干时间,安全模式结束。

当检测到副本数不足的数据块时,该块会被复制直到达到最小副本数 。

程序使用Data类模拟数据块,Namenode类作为namenode节点,Datanode类作为datanode数据节点。程序如下:

Data类

public class Data {
	private int id;
	private String msg;

	public Data(int id, String msg) {
		this.id = id;
		this.msg = msg;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
}

Datanode类

import java.util.ArrayList;
import java.util.List;

public class Datanode {
	private Namenode namenode;
	private String name;
	private List<Data> datas = new ArrayList<Data>();

	public Datanode(Namenode namenode, String name) {
		this.namenode = namenode;
		this.name = name;
	}

	public Namenode getNamenode() {
		return namenode;
	}

	public void setNamenode(Namenode namenode) {
		this.namenode = namenode;
	}

	public List<Data> getDatas() {
		return datas;
	}

	public void setDatas(List<Data> datas) {
		this.datas = datas;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

Namenode类

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

public class Namenode {
	private int replicaion = 3; // 复制因子
	private double safeRatio = 0.6; // 安全数据块的比例,大于此值可以启动集群
	private List<Integer> metaData = new ArrayList<Integer>(); // 存放元数据
	private List<Datanode> datanodes = new ArrayList<Datanode>();

	public void putMetaData(int id) {
		if (!metaData.contains(id)) {
			metaData.add(id);
		}
	}

	public static void main(String[] args) {
		Namenode namenode = new Namenode();
		System.out.println("*********启动后看下各个节点中的数据块情况*********");
		for (int i = 0; i < namenode.getDatanodes().size(); i++) {
			System.out.println(namenode.getDatanodes().get(i).getName() + ":");
			for (int j = 0; j < namenode.getDatanodes().get(i).getDatas()
					.size(); j++) {
				System.out.print(namenode.getDatanodes().get(i).getDatas()
						.get(j).getMsg()
						+ "  ");
			}
			System.out.println();
		}
	}

	private void init() {
		Datanode datanode1 = new Datanode(this, "datanode1");
		Datanode datanode2 = new Datanode(this, "datanode2");
		Data data1 = new Data(1, "data1");
		Data data2 = new Data(2, "data2");
		Data data3 = new Data(3, "data3");
		Data data4 = new Data(4, "data4");
		datanode1.getDatas().add(data1);
		datanode1.getDatas().add(data2);
		datanode1.getDatas().add(data3);
		datanode1.getDatas().add(data4);

		//让datanode2故意少几个数据块,看最后是否被复制了
		datanode2.getDatas().add(data1);	
		datanode2.getDatas().add(data3);

		datanodes.add(datanode1);
		datanodes.add(datanode2);
		initMetaData();
	}

	private void initMetaData() {
		for (int i = 0; i < datanodes.size(); i++) {
			for (int j = 0; j < datanodes.get(i).getDatas().size(); j++) {
				int id = datanodes.get(i).getDatas().get(j).getId();
				datanodes.get(i).getNamenode().putMetaData(id);
			}
		}
	}

	public Namenode() {
		init();
		safeMode(); // 先进入安全模式,然后启动
		start();
	}

	private void start() {
		System.out.println("hadoop started successfully...");
	}

	// 检查数据是否安全,有两个条件:
	// 1.数据块在集群中的个数不小于replication的值,这时是安全的数据块
	// 2.安全数据块的比例不小于safeRatio,则集群是安全的
	private void safeMode() {
		System.out.println("enter safe mode...");
		System.out.println("check data safe...");

		// 拿到数据数量的map,然后输出
		Map<Integer, Integer> dataFrequency = dataFre();
		for (Integer keys : dataFrequency.keySet()) {
			System.out.println("keys: " + keys + &qu