Hadoop底层原理

1.客户端执行hdfs fs put 本地文件系统中的文件路径 hdfs文件系统中的目录路径:hdfs fs put ./a.txt / 发送上传请求给namenode。
2.namenode根据元数据中的文件系统目录树 检测是否存在“该指定的接收上传文件的”目录,检测成功则返回成功信息给客户端。
3.客户端根据上传文件被分为多少份文件块,向namenode请求获取对应多少个datanode,每个datanode负责接收一份文件块。
4.namenode根据元数据中的datanode信息池 检测出可用的N台datanode,每个datanode负责接收一份文件块,namenode把可用的N台datanode的IP地址信息返回给客户端,
  每台datanode根据所离客户端的距离远近进行排序插入到一个列表中,离客户端距离最近的datanode排在最前面,比如顺序是 datanode1、datanode2、datanode3。
5.客户端根据离自己最近的datanode逐一建立pipeline管道连接,客户端 和 每个datanode 建立成一条 pipeline管道链接是:客户端 --> datanode1 --> datanode2 --> datanode3。
6.客户端每发送完一个文件块,其所存储该文件块的某个datanode就会返回 ack(命令正确应答)给客户端。
    1.客户端给某个datanode发送文件块时,按照在建立好的 pipeline管道链接中查找对应保存该文件块的datanode,
      逐级把文件块从一个datanode传输到另外一个databode,最终保存到指定保存该文件块的datanode中。
    2.当某个datanode保存完一个文件块后,该datanode返回 ack(命令正确应答),并按照建立好的 pipeline管道链接进行 原路返回ack(命令正确应答)给客户端,
      客户端才会继续发送下一个文件块。
7.所有datanode保存完所有的文件块并数据校验完整之后,返回成功信息给客户端

hadoop 技术详解 hadoop原理详解_hadoop 技术详解

1.客户端执行hadoop fs -get hdfs文件系统中的文件路径 本地文件系统中的目录路径:hadoop fs -get /a.txt /root/ 
  客户端发送请求给namenode,请求获取文件
2.namenode根据客户端所请求下载的文件路径,到hdfs文件系统中找到对应的文件是否存在,存在则返回该文件对应的每个文件块所存储在的每个datanode的IP地址信息,
  和 同时包括返回该datanode中保存的对应该文件的所有的每个文件块,每个datanode的IP地址信息按照离客户端的距离远近进行排序插入到一个列表中,
  距离客户端近的datanode则把他的IP地址信息插在前面。
3.客户端则根据每个datanode的IP地址信息到对应的datanode中取出对应该文件的所有的每个文件块,最终进行合并校验完整。

hadoop 技术详解 hadoop原理详解_hdfs_02

 

1.Reduce阶段 默认只有一个ReduceTask,那么Reduce阶段只输出一个文件
2.job.setNumReduceTasks(N):设置ReduceTask的个数,那么Reduce阶段输出的文件个数也为N,和ReduceTask的个数相同
3.Map阶段的多个MapTask各自输出的<key,value>根据“key.hashcode % ReduceTask个数”的规则,决定把<key,value>输出到哪个ReduceTask中,那么也即存储在哪个输出文件中。
  根据“key.hashcode % ReduceTask个数”规则所展现的效果显示: 相同key的 <key,value>都会被分配到同一个ReduceTask中,并且在同一个输出文件中。
4.切片大小默认等于块大小,即对文件以128M为一个block块进行切分,切片个数决定了MR程序启动多少个MapTask。
 
5.Map阶段(MapTask):map(起始偏移量key, 这一行内容value, Context context){ context.write(new Text(单词),new IntWritable(1)); # <单词,1> }
    1.第一步:write到内存缓冲区,直到溢出后存储到磁盘中(带有IO)。
         并且根据 “job.setNumReduceTasks(N)所设置ReduceTask个数的”规则 在磁盘中 产生相同的分区数,分区规则同为“key.hashcode % ReduceTask个数”,
         把相同key的 <key,value>都分配到同一个磁盘中的分区中,然后按照key的字典序对多个<key,value>进行排序。
         并且磁盘中每个分区各自对应一个ReduceTask,比如磁盘中第一个分区对应第一个ReduceTask,如此类推。
    2.第二步:磁盘中每个分区各自把<key,value>输出到对应的ReduceTask,比如磁盘中第一个分区输出数据到第一个ReduceTask,如此类推。
 
6.Reduce阶段(ReduceTask):reduce(单词keyIn, Iterable [1,1,...], Context context){ context.write(单词,总数); # <单词,总数> }
    1.第一步:ReduceTask把磁盘分区中送过来的数据按照key的字典序对多个<key,value>进行排序,然后把key相同的作为一组汇总成 <单词,[1,1,...]>,
         并调用reduce函数进行统计汇总单词的总次数
    2.第二步:ReduceTask把<单词,总数>输出到hdfs中的文件中