HDFS相关
1. HDFS读写文件过程
image这里描述的 是一个256M的文件上传过程 ① 由客户端 向 NameNode节点节点 发出请求②NameNode 向Client返回可以可以存数据的 DataNode 这里遵循 机架感应 原则
③客户端 首先 根据返回的信息 先将 文件分块(Hadoop2.X版本 每一个block为 128M 而之前的版本为 64M)④然后通过那么Node返回的DataNode信息 直接发送给DataNode 并且是 流式写入 同时 会复制到其他两台机器⑤dataNode 向 Client通信 表示已经传完 数据块 同时向NameNode报告⑥依照上面(④到⑤)的原理将 所有的数据块都上传结束 向 NameNode 报告 表明 已经传完所有的数据块
image读写过程链接blog
2.写HDFS时datanode处错怎么办
其中一个块坏了,只要有其它块存在,会自动检测还原。
打开一个DFSOutputStream流,Client会写数据到流内部的一个缓冲区中,然后数据被分解成多个Packet,每个Packet大小为64k字节,每个Packet又由一组chunk和这组chunk对应的checksum数据组成,默认chunk大小为512字节,每个checksum是对512字节数据计算的校验和数据。当Client写入的字节流数据达到一个Packet的长度,这个Packet会被构建出来,然后会被放到队列dataQueue中,接着DataStreamer线程会不断地从dataQueue队列中取出Packet,发送到复制Pipeline中的第一个DataNode上,并将该Packet从dataQueue队列中移到ackQueue队列中。ResponseProcessor线程接收从Datanode发送过来的ack,如果是一个成功的ack,表示复制Pipeline中的所有Datanode都已经接收到这个Packet,ResponseProcessor线程将packet从队列ackQueue中删除。在发送过程中,如果发生错误,所有未完成的Packet都会从ackQueue队列中移除掉,然后重新创建一个新的Pipeline,排除掉出错的那些DataNode节点,接着DataStreamer线程继续从dataQueue队列中发送Packet。下面是DFSOutputStream的结构及其原理,如图所示:
image我们从下面3个方面来描述内部流程:
- 创建Packet
Client写数据时,会将字节流数据缓存到内部的缓冲区中,当长度满足一个Chunk大小(512B)时,便会创建一个Packet对象,然后向该Packet对象中写Chunk Checksum校验和数据,以及实际数据块Chunk Data,校验和数据是基于实际数据块计算得到的。每次满足一个Chunk大小时,都会向Packet中写上述数据内容,直到达到一个Packet对象大小(64K),就会将该Packet对象放入到dataQueue队列中,等待DataStreamer线程取出并发送到DataNode节点。
- 发送Packet
DataStreamer线程从dataQueue队列中取出Packet对象,放到ackQueue队列中,然后向DataNode节点发送这个Packet对象所对应的数据。
- 接收ack
发送一个Packet数据包以后,会有一个用来接收ack的ResponseProcessor线程,如果收到成功的ack,则表示一个Packet发送成功。如果成功,则ResponseProcessor线程会将ackQueue队列中对应的Packet删除。
3.namenode的作用
namenode总体来说是管理和记录恢复功能。比如管理datanode,保持心跳,如果超时则排除。对于上传文件都有镜像images和edits,这些可以用来恢复。更多:深度了解namenode---其 内部关键数据结构原理简介http://www.aboutyun.com/forum.php?mod=viewthread&tid=7388
在HDFS中,namenode的服务提供整个HDFS文件系统的namespace管理,块管理等所有服务,metadata所有的相关服务都是由namenode进程在提供。其中包括 filename->blocksequence (namespace),以及block->machinelist的对应表。其中前者通过fsimage写入到本地文件系统中,而后者是通过每次HDFS启动时,datanode进行blockreport后在内存中重构的数据结构。绝大部分的情况下,namenode服务进程其实都是在被动的接收服务请求 -> 进行相应的操作和更新 –> 进行适当的返回。所以,在HDFS的程序代码中,NameNode类其实只是一个用来接收被动接收调用服务的包装,它实现了ClientProtocol接口,用来接收来自DFSClient的rpc请求;它实现了DatanodeProtocol接口,用来接收来自Datanode的各种服务请求;同时它还实现了NamenodeProtocol,用来提供跟SecondaryNameNode之间的rpc请求和通信。但实际上,对NameNode的rpc调用后面的处理逻辑,以及namespace的bookkeeping,blocksmap的维护,并没有在NameNode的程序结构中包含。真正进行以上数据结构维护的,是HDFS中的FSNamesystem类。对NameNode的各种请求,比如创建,修改,删除,移动,getLocations的操作,在NameNode内部都是通过FSNamesystem提供的接口对内部数据结构进行的访问。
4.NameNode的HA
NameNode的HA一个备用,一个工作,且一个失败后,另一个被激活。他们通过journal node来实现共享数据。
https://blog.csdn.net/daydayup_668819/article/details/70815335
5 分片
https://www.cnblogs.com/qinwangchen/p/5837940.html
totalSize:是整个Map-Reduce job所有输入的总大小。
numSplits:来自job.getNumMapTasks(),即在job启动时用org.apache.hadoop.mapred.JobConf.setNumMapTasks(int n)设置的值,给M-R框架的Map数量的提示。
goalSize:是输入总大小与提示Map task数量的比值,即期望每个Mapper处理多少的数据,仅仅是期望,具体处理的数据数由下面的computeSplitSize决定。
minSplitSize:默认为1,可由子类复写函数protected void setMinSplitSize(long minSplitSize) 重新设置。一般情况下,都为1,特殊情况除外。
minSize:取的1和mapred.min.split.size中较大的一个。
blockSize:HDFS的块大小,默认为64M,一般大的HDFS都设置成128M。
splitSize:就是最终每个Split的大小,那么Map的数量基本上就是totalSize/splitSize。
接下来看看computeSplitSize的逻辑:首先在goalSize(期望每个Mapper处理的数据量)和HDFS的block size中取较小的,然后与mapred.min.split.size相比取较大的。
一个片为一个splits,即一个map,只要搞清楚片的大小,就能计算出运行时的map数。而一个split的大小是由goalSize, minSize, blockSize这三个值决定的。computeSplitSize的逻辑是,先从goalSize和blockSize两个值中选出最小的那个(比如一般不设置map数,这时blockSize为当前文件的块size,而goalSize是文件大小除以用户设置的map数得到的,如果没设置的话,默认是1),在默认的大多数情况下,blockSize比较小。然后再取blockSize和minSize中最大的那个。而minSize如果不通过”mapred.min.split.size”设置的话(”mapred.min.split.size”默认为0),minSize为1,这样得出的一个splits的size就是blockSize,即一个块一个map,有多少块就有多少map。
5 shuffle
http://www.aboutyun.com/thread-10335-1-1.html
YARN
1.架构
imageYarn依然是Master/Slave的结构:
在资源架构层面,ResourceManager是Master,NodeManager是Slave
在应用运行期间,ApplicationMaster是Master,各个Container是Slave
ResourceManager(RM),RM是全局的资源管理器,负责整个系统的资源管理和分配。由以下两部分组成:
调度器:根据容量、队列限制条件将系统资源分配给各个应用
资源分配的单位是container,container是一个动态资源单位,它将内存、CPU、磁盘、网络等资源封装在一起,从而限定了资源使用量。
调度器是一个可插拔的组件,用户可以自己定制,也可以选择Fair或Capacity调度器
应用程序管理器:负责管理所有应用程序的以下内容:
应用提交
与调度器协商资源以启动AM
监控AM运行状态并在失败时重启它
ApplicationMaster(AM),用户提交的每个应用程序都需要包含一个AM,它的主要功能包括:
与RM调度器协商以获取资源(以container为资源单位)
将得到的任务进一步分配给内部的任务
与NM通信以启动/停止任务
监控所有任务运行状态,并在失败时重新为任务申请资源以重启任务
Tips: 当前Yarn已经实现了两个AM:
- DistributedShell:分布式的运行shell命令 -MRAppMaster:MapReduce应用的AMNodeManager(NM),是每个节点上的资源和任务管理器
定时向RM汇报本节点上的资源使用情况和各个container运行状态
接收并处理来自AM的container启动/停止等请求
Container,是Yarn中的资源抽象
它封装了节点上多个维度的资源(目前Yarn只支持CPU和内存两种资源)
它与slot的不同之处在于,slot是静态的(每个slot的资源相同),container是动态的(每个container的资源可以不同)。
2.提交作业
image当用户向YARN中提交一个应用程序之后,Yarn分两大阶段运行该应用:
第一个阶段是启动AM
第二个阶段是由AM创建应用程序,为它申请资源,并监控运行过程,直到运行结束
步骤1:用户向YARN提交应用,其中包括AM、启动AM的命令、用户程序等
步骤2:RM为该应用分配第一个Container,并与对应的NM通信,要求它在这个Container中启动应用的AM
步骤3:AM向RM注册,这样用户可以通过RM查看应用的状态。然后AM为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复以下步骤4~7
步骤4:AM采用轮询的方式通过RPC协议向RM申请和领取资源
步骤5:一旦AM获得资源,便与对应的NM通信,要求它启动任务
步骤6:NM为任务设置好运行环境(包括环境变量、JAR包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过该脚本启动任务
步骤7:各个任务通过某个RPC协议向AM汇报自己的状态和进度,以让AM随时掌握状态,从而可以在任务失败时重启任务
步骤8:应用程序运行完成后,AM向RM申请注销并关闭自己。
3. yarn 组件介绍
client
image-
Client 通过RPC函数获取唯一的ApplicationID
-
Client通过RPC函数将ApplicationMaster提交到RM上
YARN ApplicationMaster
imageAM-RM
-
注册
-
申请资源
-
告诉执行完毕
AM通过RPC函数registerApplicationMaster向ResourceManager注册。
注册信息封装成RegisterApplicationMasterRequest对象。返回值为RegisterApplicationMasterResponse对象。包含属性:
-
maximumCapability 最大可申请的单个container占用的资源量
-
client_t_am_token_master_key
-
Application_ACLs
AM通过RPC函数allocate申请资源。发送参数为AllocateRequest。主要包含以下属性
-
ask请求的资源列表。每一个资源用Resourcerequest队形表示。
-
release释放的container列表
-
response_id 本次通信的应答id
-
progress应用程序执行进度
-
blacklist_request
返回值为AllocateResponse。
-
a_m_command am需要执行的命令。
-
response_id 本次通信的应答id
-
allcated_containers 分配的container列表
-
Completed_container_statuses 运行完成container状态列表
-
limit集群可用资源总量
-
Updated_nodes 当前集群所有节点运行状态列表
AM通过RPC函数finishApplicationMaster告诉执行完毕。参数FinishApplicationMasterRequest。返回值FinishApplicationMasterResponse。
imageAM-NM
-
启动container
-
查询状态
-
释放container
ApplicationMaster将申请到的资源二次分配给内部的任务,通过RPC函数startContainer与NM通信启动container。
-
参数startContainersRequest。
-
container_launch_context 封装了container执行环境
-
container_token 启动时候的安全令牌
-
-
返回值startContainersResponse
-
succeeded_requests 成功运行的container列表
-
failed_requests 运行失败的container列表
-
为了实时掌握container运行状态。AM通过RPC函数getcontainerstatus向NM询问container运行状态。一个container运行万,可以通过stopcontainer释放container。
resource manager
image-
与客户端交流,处理请求
-
启动管理AM,并在其运行失败时重启AM
-
管理NM,接受汇报信息,及下达管理命令
-
资源管理与调度
-
交互模块:RM对普通用户、管理员、Web提供了三种对外服务:
-
ClientRMService:为普通用户提供服务,它处理来自客户端的各种RPC,比如
-
应用提交
-
终止应用
-
获取应用状态等
-
-
AdminService:为管理员提供的独立接口,主要目的是为了防止大量普通用户请求阻塞管理员通道,提供如下功能:
-
动态更新节点列表
-
更新ACL列表
-
更新队列信息等
-
-
WebApp:提供一个Web界面来让用户更友好的获知集群和应用的状态
-
-
NM管理模块:用来管理NM的模块,主要包含以下三个组件:
-
ResourceTrackerService:处理来自NodeManager的请求,主要包括:
-
注册:注册是NM启动时发生的行为,NM提供的信息包括:节点ID、可用资源上限信息等
-
心跳:心跳是周期行为。NM提供的信息包括:各个Container运行状态、运行的Application列表、节点健康状态等。RM返回的信息包括:等待释放的Container列表、Application列表等
-
-
NMLivelinessMonitor:监控NM是否活着,如果NM在一定时间(默认10m)内未上报心跳,则认为它死掉,需要移除
-
NodesListManager:维护正常节点和异常节点列表,管理exclude(类似黑名单)和include(类似白名单)节点列表,这两个列表均是在配置文件中设置的,可以动态加载。
-
-
AM管理模块:主要是用来管理所有AM,主要包括:
-
ApplicationMasterService(AMS):处理来自AM的请求,包括:
-
注册:是AM启动时发生的行为,信息包括:
-
AM的启动节点、对外RPC端口、trackingURL等
-
心跳:是周期行为。AM提供的信息包括:所需资源的描述、待释放Container列表、黑名单列表等。AMS返回的信息包括:新分配的Container、失败的Container、待抢占的Container列表等
-
-
AMLivelinessMonitor:监控AM是否活着,如果AM在一定时间(默认10m)内未上报心路,则认为它死掉,它上面正在运行的Container将会被置为失败状态,而AM本身会被分配到另一个节点上(用户可以指定重试次数,默认5)
-
ApplicationMasterLauncher:与某个NM通信,要求它为某个应用程序启动AM
-
-
应用管理模块:主要是各个应用外围的管理,并不涉及到应用内部
-
ApplicationACLsManager:管理应用程序访问权限,包含两部分:
-
查看权限:主要用于查看应用程序基本信息
-
修改权限:主要用于修改应用程序优先级、杀死应用程序等
-
-
RMAppManager:管理应用程序的启动和关闭
-
ContainerAllocationExpirer:当AM收到RM新分配的Container后,必须在一定时间(默认10m)内在对应的NM上启动该Container,否则RM将强制回收该Container,而一个已经分配的Container是否该被回收则是由ContainerAllocationExpirer决定和执行的
-
-
状态机管理模块:RM使用有限状态机维护有状态对象的生命周期,状态机的引入使得Yarn的架构设计清晰,RM内部的状态机有:
-
RMApp:维护一个应用程序的整个运行周期,包括从启动到运行结束的整个过程由于一个APP的生命周期可能会启动多个运行实例(Attempt),RMApp维护的是所有的这些Attempt
-
RMAppAttempt:一次应用程序的运行实例的整个生命周期,可以理解为APP的一次尝试运行
-
RMContainer:一个Container的运行周期,包括从创建到运行结束的整个过程。
-
RM将资源封装成Container发送给应用程序的AM,AM在Container描述的运行环境中启动任务。Yarn不支持Container重用,一个Container用完后会立刻释放
-
RMNode:维护了一个NM的生命周期,包括从启动到运行结束的整个过程
-
-
安全模块:RM自带了非常全面的权限管理机制,主要包括:
-
ClientToAMSecretManager
-
ContainerTokenSecretManager
-
ApplicationTokenSecretManager等,由于这块非常复杂,可以找个专题讨论,这里先不展开
-
-
调度模块:主要包含一个组件ResourceScheduler。是资源调度器,它按照一定的约束条件(比如队列容量限制等)将集群中的资源分配给各个应用程序,目前主要考虑内存和CPUResourceScheduler是一个可插拔式的模块,自带三个调度器,用户可以自己定制。
-
FIFO:先进先出,单用户
-
FairScheduler:公平调度器(FairScheduler基本上具备其它两种的所有功能)
-
CapacityScheduler:容量调度器
-
node manager
image
网友评论