————————————————————————————————————————————————————
面试题
第一套
1.hadoop运行原理
包括HDFS和Mapreduce两部分。
1)HDFS自动保存多个副本,移动计算。缺点是小文件存取占用namenode内存,写入只支持追加,不能随机修改。
它存储的逻辑空间称为block,文件的权限类似linux。整体架构分三种节点,NN,SNN,DN
NN 负责读写操作保存metadata(Ownership Permission blockinfo)
SNN 负责辅助NN合并fsimage和edits,减少nn启动时间
DN 负责存数据,每个数据(文件)分割成若干block,每个block默认3个副本。启动后像NN发送心跳保持联系
NN保存的metadata在hdfs启动后加载到计算机内存,除block位置信息的metadata保存在OS文件系统中的fsimage文件中,对metadata的操作日志保存在OS文件系统中的edits文件中。block位置信息是hdfs启动后由DN上报NN再加载到内存的。
HDFS的安全模式:直到NN完全加载完metadata之前的这段时间。期间不能写入文件,DN检查各个block完整性,并修复。
2)MapReduce
离线计算框架,过程分为split map shuffle reduce四个过程
架构节点有:Jobtracker TaskTracker
Split将文件分割,传输到mapper,mapper接收KV形式的数据,经过处理,再传到shuffle过程。
Shuffle先进行HashPartition或者自定义的partition,会有数据倾斜和reduce的负载均衡问题;再进行排序,默认按字典排序;为减少mapper输出数据,再根据key进行合并,相同key的数据value会被合并;最后分组形成(key,value{})形式的数据,输出到下一阶段
Reduce输入的数据就变成了,key+迭代器形式的数据,再进行处理
2.MapReduce原理
逻辑上:
1、split
2、map
3、shuffle
4、reduce
四个过程
物理上:
JobTracker节点:JobTracker创建每一个Task(即MapTask和ReduceTask)
并将它们分发到各个TaskTracker服务中去执行。负责调度Job的每一个子任务task运行于TaskTracker上。
TaskTracker节点:运行在多个节点上的slaver服务。TaskTracker主动与JobTracker通信,接收作业,并负责直接执行每一个任务。TaskTracker都需要运行在HDFS的DataNode上
3.hdfs存储机制
1) client端发送写文件请求,namenode检查文件是否存在,如果已存在,直接返回错误信息,否则,发送给client一些可用namenode节点
2) client将文件分块,并行存储到不同节点上datanode上,发送完成后,client同时发送信息给namenode和datanode
3) namenode收到的client信息后,发送确信信息给datanode
4) datanode同时收到namenode和datanode的确认信息后,提交写操作。
4.用MapReduce找出存在公共好友的两个人
数据样本:
A:B,C
B:A,E
C:A,D
D:C
E:B
import java.io.IOException;
import java.util.ArrayList;
//import java.util.Collection;
//import java.util.Map.Entry;
//import java.util.HashMap;
import java.lang.Iterable;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
//import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.util.ToolRunner;
import org.apache.hadoop.util.Tool;
import org.apache.commons.lang.StringUtils;
public class FindUsers extends Configured implements Tool {
static class Map extends Mapper<LongWritable, Text, Text, Text> {
public void map(LongWritable key, Text val, Context context) throws IOException, InterruptedException {
String line = val.toString();
String user = line.split(":")[0];
String[] friends = line.split(":")[1].split(",");
String joined_friends = StringUtils.join(friends, ",");
for(String friend : friends) {
int result = friend.compareTo(user);
if(result > 0) {
context.write(new Text(user + "," + friend), new Text(joined_friends));
}
else if(result < 0) {
context.write(new Text(friend + "," + user), new Text(joined_friends));
}
}
}
}
static class Reduce extends Reducer<Text, Text, Text, Text> {
public void reduce(Text key, Iterable<Text> vals, Context context) throws IOException, InterruptedException {
String string_key = key.toString();
String[] users = string_key.split(",");
ArrayList<String> list = new ArrayList<String>();
int i = 0;
String state = "Off";
for(Text val : vals) {
i++;
String[] all_people = val.toString().split(",");
ArrayList<String> inner_list = new Arra