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