客户端向HDFS读写数据流程

客户端向HDFS写数据流程

1. 客户端向Namenode请求上传文件 /aaa/xxx.log
2. Namenode 检查自己的元数据,看看元数据下有没有这个目录,假设满足条件(没有这个目录可以上传)
    响应客户端的请求[客户端可以上传]
3. 客户端RPC请求上传1个Block(0-128M),请返回DataNode(返回几个DataNode是客户端配置的,默认3个)
4. 返回(dn1,dn3,dn4)给客户端
    为什么要给客户端返回这三台机器呢?
        考虑因素: 空间/距离
            1. 第1个副本(dn1),要看DataNode的空间(剩余存储空间)和距离(同一个机架上的距离一样,而不是谁的网线长短)
            假如这几台机器的空间差不多,NameNode就随机返回一台;
            2. 第2个副本(dn3),考虑跨机架挑选1个DataNode,增加副本的可靠性
            3. 第3个副本就在第1个副本同机架另外挑选1台DataNode存放
        怎么能让NameNode知道哪个datanode在1个机架,哪个datanode在另1个机架,这个要配个文件,
        配机架感知。[就是在配置文件里写死了,哪个机架有哪几台DataNode(网咯拓扑)]
5. 客户端会找最近的(将要上传副本到的那台机器)一台DataNode[假如找的是dn1],请求建立Block传输通道channel[本地流,以供写入数据]
    5.1 dn1接收到请求看到还有2台机器(dn3、dn4),dn1就向dn3发送请求建立管道
    5.2 dn3接收到请求看到还有一台dn4,就向dn4发送请求建立管道
6.1 dn4建立管道成功后,给dn3发送响应,建立管道成功
6.2 dn3再给dn1发送响应,建立管道成功
    这样一来,管道 PipeLine就建立成功了
7. 客户端读取本地的1块数据(默认128M),向dn1传输数据(数据是以1个1个packet[默认64k]的形式上传的)
    packet是以chunk(Byte)为单位校验
    7.1 每个DataNode写入磁盘之前都会有1个缓冲区(ByteBuf),先写入缓冲区,再写入本地磁盘
         因为每个packet只有64k,所以dn写入之后,基本上后面的dn3和dn4也都复制上传完成了[几乎同步完成]
         每个DataNode上传成功packet 都会向前面的DataNode反馈说上传成功,第一个DataNode才给客户端说上传成功
    假如说是后面两台DataNode节点没有上传成功,但是只要是第1台上传成功了,客户端就认为上传成功了
    [因为NameNode最后会帮客户端异步去复制,省得客户端一直阻塞,说没成功再来,没成功再来];
    假如第1台也失败了,客户端就会找NameNode,告诉他这台DataNode不行,再换,然后重新返回DataNode,重新上传;
8. 上传完了第1个Block,客户端会再次向NameNode发送请求说要上传第2块Block,然后重新走刚刚的流程
总结:
    这样一来,NameNode的元数据就记录了,上传的文件的 路径、文件有几个Block、Block副本在哪些机器

客户端向HDFS读数据流程

1. 客户端向NameNode请求下载/aa/xx.log
2. NameNode的元数据上面查看/aa/xx.log,然后查询得到:3个Block(Block1,Block2,Block3)、{Block1:dn1,dn3,dn4 Block2:dn1,dn4,dn5...}
    并返回给客户端目标文件的元数据信息
3. 客户端要下载第1个Block,然后就去找副本所在节点距离它最近的(dn1),建立管道,请求读取Block1
4. dn1建立本地流,fileInpuStream,dn1建立 NIO socket - socketOutPutStream
5. 客户端建立socketInputStream,还有fileOutPutStream 写入本地 如:c:/xxx.log
6. dn1 传输通过通道传输数据
Block1上传到客户端完成后,客户端会再去找第2块Block 跟找Block1是一样的,还有Block3

MR Yarn的提交流程

Yarn:
    只负责程序运行所需资源的分配回收等调度任务,与应用程序的内部运行工作机制完全无关,
    所以Yarn已经成为一个通用的资源调度平台,许许多多的运算框架都可以借助他来实现资源管理,
    比如:MR/SPARK/FLINK/TEZ...
NodeManager分配container基于:
Linux的资源隔离机制cgroup  比如:docker也是基于此

1. 客户端所在节点,运行jar包,main方法里,job.submit() 
  YarnRunner(Proxy[实现了ClientProtocol])找Yarn集群的老大ResourceManager申请提交1个Application
2. ResourceManager返回Application提交资源路径:hdfs://xxx/xx.staging 和 application_id
3. YarnRunner提交job运行所需的资源文件,提交到hdfs://xxx/xx.staging/application_id
                                                                                    /job.split
                                                                                    /job.xml
                                                                                    wc.jar
4. 客户端通过RPC调用 告诉ResourceManager 资源提交完毕,申请运行mrAppMaster [后面的事情就和客户端没关系了]
ResourceManager运行的时候不止是接收这1个程序,还可能接收其他的程序提交,所以ResourceManager也有不同的调度策略[三种策略]:
    4.1 FIFO[先进先出]:任务在队列里,要先运行完第1个,再运行第2个
        [这个时候是可以接收其他的任务提交的,只不过要等][这个在老版本里是默认的]
    4.2 Fair:每个job提交后,都会分配一点点资源给他们
    4.3 capacity:第1个job提交之后,把资源全部给他,当第2个job来的时候,第1个job的一些task可能就已经运行完了,
        这样的话空余出来的资源就可以给后来提交的job了,如果后来的job需要的资源很少,可能直接就运行完了,运行完了,            还可以把这些资源给之前的应用继续使用
        [新版本的默认就是capacity调度策略]
5. 将用户的请求初始化成一个task
6. 因为nodeManager和NamenodeManager一直保持着心跳,所以会去领取任务(task),假如nm1领取到任务
7. nm1就会生成1个container容器[分配了cpu + ram],到HDFS上下载资源并启动mrAppMatser
8. mrAppMatser向NamenodeManager申请运行MapTask的容器
9. 假如这时候nm2和nm3领取到task任务,然后分别在各自的节点生成1个容器[这个容器就是1个进程叫做YarnChild,可以通过jps查看]
10. mrAppMatser发送程序启动脚本[java -cp...]给nm2和nm3来运行MapTask
        mrAppMatser会监管这些MapTask的运行情况,如果哪个MapTask运行失败,
        他还会去找NamenodeManager重新申请1个nodeManager来生成container来运行MapTask
        如果他发现有一个MapTask运行的特别慢,他还会去重新申请1个新的nodeManager生成container,
        两个同时处理一个切片,看哪个先执行完,就用哪个的结果文件作为reduce的输入 **[推测执行]**
11. 当MapTask运行完成之后,mrAppMatser知道MapTask的输出文件[分区且排序,不如有3个分区]在哪[container里的工作目录]
12. mrAppMatser向NamenodeManager申请3个容器,来运行reduceTask程序
13. 这3个容器运行的reduce task会向相对应map task的nodeManager拉取相对应分区的数据过来
14. reduce 对数据进行merge + 排序 ,调用reduce方法 ,输出结果
15. 当mrAppMatser执行完了之后就会去找ResourceManager申请注销自己

总结hadoop1和hadoop2的比较:

a) 1里面没有yarn,只有jobTracker,负责资源调度和应用运算流程管理,
如果后面还有任务提交,还是他来管理和调度资源,这样的话都在1个节点上,
很消耗性能,而且当jobTracker挂掉之后,任务都不能运行了。
b) 2里面有yarn,只要把任务提交给yarn ,然后yarn进行资源管理就可以了,
appMaster来负责应用运算流程管理,当一个appMaster挂了之后,也不会影响
其他应用的作业