日期:2014-05-16 浏览次数:20450 次
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