HDFS部分java
详情参考hadoop相关性能指标说明。这里列出一些hdfs的关键指标node
(1)rpc相关shell
rpc.rpc.RpcQueueTimeAvgTime:rpc平均队列时长apache
rpc.rpc.RpcProcessingTimeAvgTime:rpc平均处理时长api
rpc.rpc.CallQueueLength:rpc队列请求队列长度安全
rpc.rpc.NumOpenConnections:rpc链接数网络
直接反应rpc性能的指标,若是出现明显增多,则说明namenode的性能异常。架构
(2)jvm相关并发
jvm.JvmMetrics.MemHeapUsedM:jvm使用堆内存大小app
jvm.JvmMetrics.MemNonHeapUsedM :jvm非堆内存使用大小
jvm.JvmMetrics.ThreadsBlocked:阻塞的线程数
jvm.JvmMetrics.ThreadsWaiting:无限期等待线程数
jvm.JvmMetrics.ThreadsTimedWaiting:等待线程数
(3)namespace相关
TotalFiles:总的文件数量
TotalBlocks:总的block数量
PercentUsed:集群hdfs使用百分比
BlockPoolUsedSpace:集群该namespace的hdfs使用容量大小
NumLiveDataNodes:存活的DN数量
NumDeadDataNodes:丢失的DN数量
MissingBlocks:丢失的block数量
(4)datenode相关
ReadBlockOpAvgTime:读取block的平均时间
WriteBlockOpAvgTime:写数据块的平均时间
(5)
ugi.UgiMetrics.GetGroupsAvgTime:获取组信息平均时长
二,请列出客户端和namenode之间的通讯协议,以及协议的经常使用方法和做用。
org.apache.hadoop.hdfs.protocol.ClientProtocol
经常使用接口
建立文件:建立一个新的文件
public HdfsFileStatus create(String src, FsPermission masked,
String clientName, EnumSetWritable<CreateFlag> flag,
boolean createParent, short replication, long blockSize,
CryptoProtocolVersion[] supportedVersions)
throws AccessControlException, AlreadyBeingCreatedException,
DSQuotaExceededException, FileAlreadyExistsException,
FileNotFoundException, NSQuotaExceededException,
ParentNotDirectoryException, SafeModeException, UnresolvedLinkException,
SnapshotAccessControlException, IOException;
追加文件:打开一个文件,用于在该文件上新增数据。
public LocatedBlock append(String src, String clientName)
throws AccessControlException, DSQuotaExceededException,
FileNotFoundException, SafeModeException, UnresolvedLinkException,
SnapshotAccessControlException, IOException;
获取数据块位置:获取数据块的保存位置
public LocatedBlocks getBlockLocations(String src,
long offset,
long length)
throws AccessControlException, FileNotFoundException,
UnresolvedLinkException, IOException;
报告坏块:当客户端发现获取的数据块有问题时,会报告给namenode
public void reportBadBlocks(LocatedBlock[] blocks) throws IOException
增长数据块:写入数据时,申请新的数据块
public LocatedBlock addBlock(String src, String clientName,
ExtendedBlock previous, DatanodeInfo[] excludeNodes, long fileId,
String[] favoredNodes)
throws AccessControlException, FileNotFoundException,
NotReplicatedYetException, SafeModeException, UnresolvedLinkException,
IOException;
放弃申请的数据块:当写数据块出错误时,能够放弃该数据块
public void abandonBlock(ExtendedBlock b, long fileId,
String src, String holder)
throws AccessControlException, FileNotFoundException,
UnresolvedLinkException, IOException;
持久化数据:当须要关闭文件时,须要首先调用该函数,对数据进行持久化
public void fsync(String src, long inodeId, String client,
long lastBlockLength)
throws AccessControlException, FileNotFoundException,
UnresolvedLinkException, IOException;
关闭文件:数据持久化以后,进行文件的关闭
public boolean complete(String src, String clientName,
ExtendedBlock last, long fileId)
throws AccessControlException, FileNotFoundException, SafeModeException,
UnresolvedLinkException, IOException;
获取文件或者目录的信息:
public HdfsFileStatus getFileInfo(String src) throws AccessControlException,
FileNotFoundException, UnresolvedLinkException, IOException;
获取目录的空间信息:
public ContentSummary getContentSummary(String path)
throws AccessControlException, FileNotFoundException,
UnresolvedLinkException, IOException;
设置文件/目录权限
public void setPermission(String src, FsPermission permission)
throws AccessControlException, FileNotFoundException, SafeModeException,
UnresolvedLinkException, SnapshotAccessControlException, IOException;
设置文件所属用户和组:
public void setOwner(String src, String username, String groupname)
throws AccessControlException, FileNotFoundException, SafeModeException,
UnresolvedLinkException, SnapshotAccessControlException, IOException;
设置文件的修改时间和访问时间:
public void setTimes(String src, long mtime, long atime)
throws AccessControlException, FileNotFoundException,
UnresolvedLinkException, SnapshotAccessControlException, IOException;
设置文件副本个数:
public boolean setReplication(String src, short replication)
throws AccessControlException, DSQuotaExceededException,
FileNotFoundException, SafeModeException, UnresolvedLinkException,
SnapshotAccessControlException, IOException;
删除文件/目录:
public boolean delete(String src, boolean recursive)
throws AccessControlException, FileNotFoundException, SafeModeException,
UnresolvedLinkException, SnapshotAccessControlException, IOException;
文件/目录重命名:
public boolean rename(String src, String dst)
throws UnresolvedLinkException, SnapshotAccessControlException, IOException;
建立目录:
public boolean mkdirs(String src, FsPermission masked, boolean createParent)
throws AccessControlException, FileAlreadyExistsException,
FileNotFoundException, NSQuotaExceededException,
ParentNotDirectoryException, SafeModeException, UnresolvedLinkException,
SnapshotAccessControlException, IOException;
获取一个目录下的项目:
public DirectoryListing getListing(String src,
byte[] startAfter,
boolean needLocation)
throws AccessControlException, FileNotFoundException,
UnresolvedLinkException, IOException;
管理方法:
设置目录配额:
public void setQuota(String path, long namespaceQuota, long diskspaceQuota)
throws AccessControlException, FileNotFoundException,
UnresolvedLinkException, SnapshotAccessControlException, IOException;
设置安全模式:
public boolean setSafeMode(HdfsConstants.SafeModeAction action, boolean isChecked)
throws IOException;
刷新节点:
public void refreshNodes() throws IOException;
保存image文件,并重置editlog
public void saveNamespace() throws AccessControlException, IOException;
三,请简述hdfs dfs -du 操做的内部细节,结合实际场景描述一下该操做的代价。
Hdfs dfs –du统计指定文件或目录下各个子项目的容量。-s参数:合计统计。-h参数:转换成易读形式显示
实现细节:
解析参数验证合法性——>经过rpc调用namenode远程方法——> FSNamesystem. getContentSummary(final String srcArg)——>返回结果
FSNamesystem. getContentSummary(final String srcArg)方法的实现比较复杂。他会递归统计各个项目的大小,而且在统计用量的时候会给namespace加锁。因此在du一个很是大的目录时,读锁的时间会很长,在此期间hdfs不提供写服务,会形成写请求挤压,进而致使整个集群性能降低。
1,上锁:读锁容许namespace提供读服务,可是禁止写锁的访问。
2,递归
四,hdfs为何不适合存放大量小文件,小文件过多的常看法决方案是什么?
小文件:不知足一个块大小而且文件自己很是小的文件(好比大量不大1MB的文件),具体的阈值能够根据hdfs的具体状况而定。
小文件过多的影响:
(1)文件的元数据信息保存在namenode的内存中,而具体的数据保存在datanode的磁盘上。小文件过多,会出现hdfs的物理空间很充足可是namenode的内存空间很紧张。使得在管理同等数据量的状况下,namende的压力显著增大,形成datanode空间浪费。
(2)在没有进行输入合并的mr任务中,针对每一个文件都会启动一个map任务读取数据。小文件过多,会致使处理相同数据量的任务时map任务个数大大增长。增大集群压力的同时还会下降任务运行效率。
常看法决方案:
(1)文件归档: Hadoop archives
(2)冷数据压缩
(3)更改文件的写出方式:好比经过写HBase的方式进行数据的写入,例如将文件名和文件内容,做为具体数据直接写入hbase
五,请概述namenode的ha机制,尽量多的列出会引起namenode的主备切换的缘由,以及ha切换对集群有何影响。
HA机制:采用共享存储的原理,zookeeper用来作主从选举,JournalNodes用来作编辑日志文件的存储。
架构图以下
主进程是zkfc(ZKFailoverController),有两个关键服务HealthMonitor,ActiveStandbyElector
HealthMonitor:监控namenode的状态
ActiveStandbyElector:主从选举,利用了zookeeper临时节点的特性
Zkfc会在zookeeper中建立两个节点:
(1)ActiveStandbyElectorLock:临时节点,用来作主从选举
(2)ActiveBreadCrumb:永久节点,存放当前处于active namenode的节点信息,主要用来防止脑裂。
过程:
主从竞争:当namenode启动后,均会将自身状态置为standby,而后尝试着在zookeeper上建立ActiveStandbyElectorLock 临时目录,zookeeper能够保证只有一个请求建立成功,其它的请求失败。建立成功的namenode,会将自身状态转换为active,并将自身信息写入ActiveBreadCrumb 节点。建立ActiveStandbyElectorLock失败的namenode保持自身的standby状态不变,而后在ActiveStandbyElectorLock注册watcher监听该节点状态。
主从切换:当HealthMonitor检测到namenode故障时,若是须要进行切换,则会断开zookeeper的链接释放ActiveStandbyElectorLock节点,而后将自身状态设置为standby,同时将ActiveBreadCrumb里面的数据删除,休息必定的时间再次加入选举。在休息的期间,其它节点通常会抢到ActiveStandbyElectorLock锁,并成为active。
当active namenode正常运行,可是zkfc和zookeeper因为心跳超时致使ActiveStandbyElectorLock节点释放,可是ActiveBreadCrumb中的数据没有删除成功时。其它节点若是抢到ActiveStandbyElectorLock锁,会首先判断ActiveBreadCrumb中的数据,发现是另一个节点数据,会尝试经过rpc请求将原先的active namenode置为standby,若是原先的active namenode特别繁忙,对该rpc请求没法作出相应时。则zkfc会根据dfs.ha.fencing.methods配置方法进行处理(通常是,ssh远程执行fuser暴力杀死namenode进程)
致使namenode切换常见缘由:
总结起来讲,只要是zkfc释放了zookeeper中的ActiveStandbyElectorLock临时节点,就会致使切换。zookeeper临时节点的特性:zk和客户端的会话结束,临时节点删除。因此要么是zkfc主动释放了临时节点,要么是会话结束zk自动删除临时节点。根据这两个线索,结合namenode和zkfc就能够总结出namenode切换的常见缘由
HAServiceProtocol协议的两个方法:getServiceStatus和monitorHealth
Ha切换对集群的影响:
示例:若是namendoe负载很大,并且切换后,致使客户端先访问了standby namenode,那么hdfs效率会明显下降。
YARN部分
一, GBD平台队列配置中支持对oozie任务个数的并发限制,请问是基于什么缘由要这么作?这样作的优缺点是什么?若是不这样作,你有其它办法吗?
<queue name="default">
<maxRunningApps>10</maxRunningApps>
<maxRunningOozieApps>5</maxRunningOozieApps>
<minResources>0mb, 0vcores</minResources>
<maxResources>184320mb, 60vcores</maxResources>
<schedulingPolicy>DRF</schedulingPolicy>
<maxAMShare>-1.0</maxAMShare>
<weight>1.0</weight>
<aclSubmitApps>hadoop,oozie</aclSubmitApps>
<aclAdministerApps>hadoop,oozie</aclAdministerApps>
</queue>
缘由:利用oozie提交shell action任务时,oozie会将任务封装到一个只有一个map的mr任务(oozie launch任务),在该map中执行具体的逻辑。当咱们写的shell脚本中须要启动新的application时(好比:hive –e ”select count(1) from dual”),就会出现一个yarn application中启动新的yarn application。由于队列资源和任务个数的限制,当oozie launch用尽了队列资源,或者达到了队列任务个数限制。那么oozie launch中则没法启动新的application任务,致使队列死锁。
优势:能够解决队列死锁问题,配置简单。
缺点:(1)有很大几率形成资源浪费。为了不死锁,咱们要确保当oozie launch任务个数达到限制时,队列资源要有大部分的剩余。由于咱们没法判断该oozie任务中是否会启动新的application,因此当大量oozie任务并发时会形成资源浪费。(2)当队列中oozie任务和非oozie任务同时运行时,若是队列资源用满,oozie任务将没法启动子application直到有非oozie任务运行完毕腾出资源,这样会形成oozie任务的延迟。
其它解决办法:
oozie提交任务时,分别指定oozie.launcher.mapreduce.job.queuename和mapreduce.job.queuename参数,使得oozie launcher和实际的执行任务运行在不一样队列。
二,在fairscheduler下,尽量列举出哪些状况会形成某些任务一直处于ACCEPTED状态。若是遇到这种状况,你会从哪几个方面进行处理?
applicationmaster状态机以下:
Yarn状态机的特性:状态机处于某一状态时,只有在接收到相应的事件时才会进行转改的转换。根据rmapp状态机图,处于accepted状态的任务只有在接受到以下事件之一时才会进行状态的切换(RMAppEventType.ATTEMPT_REGISTERED, RMAppEventType.ATTEMPT_FAILED, RMAppEventType.ATTEMPT_FINISHED, RMAppEventType.KILL等)。在这里咱们只关心ACCEPTED状态到RUNNING状态的切换,便是RMAppEventType.ATTEMPT_REGISTERED事件。
结合代码分析,正常状况下,应用在进入ACCEPTED状态和接收到ATTEMPT_REGISTERED之间主要作了以下工做:
其中RMAppAttemptImpl从NEW到LAUNCHED之间主要作了以下工做:
其中
若是resourcemanager负载高,网络延迟等会形成(1)耗时增多
若是集群资源分配不合理或者资源使用负载高,第(2)步会耗时增多
若是队列运行任务个数达到限制或者application master占用资源达到限制,第(2)步会耗时增多,直到知足条件
若是am和nm之间网络延迟会形成(3)步耗时增多
三,Gbd平台上在使用oozie提交任务(特别是spark任务)的时候常常出现以下异常,请问是什么缘由,该如何处理?
Container [pid=9775,containerID=container_1493900293742_1660_01_000002] is running beyond physical memory limits. Current usage: 3.0 GB of 3 GB physical memory used; 31.0 GB of 12.6 GB virtual memory used. Killing container. Dump of the process-tree for container_1493900293742_1660_01_000002 : |- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE |- 10092 10085 9775 9775 (java) 11310 856 29477392384 646254 /usr/lib/jdk/bin/java -cp /appcom/spark-config/:/appcom/spark/lib/spark-assembly-1.6.1-hadoop2.6.0.jar:/appcom/spark/lib/datanucleus-rdbms-3.2.9.jar:/appcom/spark/lib/datanucleus-api-jdo-3.2.6.jar:/appcom/spark/lib/datanucleus-core-3.2.10.jar:/appcom/hadoop-config/:/appcom/hadoop-config/
缘由:咱们平台是将spark任务封装成shell脚本经过oozie shell action提交的。因此oozie launcher任务至关于spark的driver。由于oozie launcher任务是一个单map的mr任务,平台默认一个map的内存空间为3G,常常不知足spark driver对内存的要求。
处理:使用oozie提交spark任务时,经过配置ozie.launch.mapreduce.map.memory.mb参数,调大内存配置
四,请列出ResourceManager和ApplicationMaster之间的通讯协议,以及协议的经常使用方法和做用。
org.apache.hadoop.yarn.api.ApplicationMasterProtocol
am向rm注册:
public RegisterApplicationMasterResponse registerApplicationMaster(
RegisterApplicationMasterRequest request)
throws YarnException, IOException;
am向rm申请资源:
public AllocateResponse allocate(AllocateRequest request)
throws YarnException, IOException;
am向rm报告应用结束:
public FinishApplicationMasterResponse finishApplicationMaster(
FinishApplicationMasterRequest request)
throws YarnException, IOException;
五,请概述resourcemanager的ha机制,尽量多的列出会引起resourcemanager的主备切换的缘由,以及ha切换对集群有何影响。
ResourceManager的ha也是采用共享存储的原理:通常的作法是配置一个zookeeper集群用来进行主从选举和任务状态信息的存储。主从选举依然采用zookeeper临时节点的特性,任务状态信息的存储则是为了进行任务的恢复。
不像hdfs有一个专门的zkfc进程来进行ha的管理,resourcemanager的ha关机进程是内嵌在自身服务当中的。
选举服务:
org.apache.hadoop.yarn.server.resourcemanager.EmbeddedElectorService
存储服务
接口:org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore
咱们选择的实现:org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore
zookeeper相关节点:
ActiveStandbyElectorLock:临时节点,进行主从选举
ActiveBreadCrumb:持久节点,存放当前active数据
rmstore:存放rm和application状态信息,便于恢复
选举过程:
Rm启动后,先将自身状态置为standby状态。而后初始化EmbeddedElectorService服务(创建zookeeper链接,初始化相关节点),以后进入选举。选举方法是尝试在zookeeper中建立一个临时节点ActiveStandbyElectorLock,zookeeper能够确保只有一个请求能够建立成功。若是建立成功则说明选举成功,而后会将自身状态设置为active并启动相关服务(RMActiveServices),而且将自身信息写入ActiveBreadCrumb节点。若是建立临时节点失败,则说明选举失败,保持自身standby状态不变,同时向ActiveStandbyElectorLock注册watcher,监听该节点状态。
主从切换:active resourcemanager故障时(服务挂掉),则会断开zookeeper的链接释放ActiveStandbyElectorLock节点,而后将自身状态设置为standby,同时将ActiveBreadCrumb里面的数据删除。Standby resourcemanager监控到ActiveStandbyElectorLock节点被删除,则会去建立它,一旦建立成功接表明选举成功。接下来就会将自身状态置为active并启动相关服务(RMActiveServices),将自身信息写入ActiveBreadCrumb中。
注:咱们目前使用的hadoop版本resourcemanager的ha没有fence机制
形成切换的缘由:
总结起来讲,只要是resourcemanager释放了zookeeper中的ActiveStandbyElectorLock临时节点,就会致使切换。zookeeper临时节点的特性:zk和客户端的会话结束,临时节点删除。因此要么是resourcemanager主动释放了临时节点,要么是会话结束zk自动删除临时节点。根据这两个线索,结合resourcemanager和EmbeddedElectorService就能够总结出resourcemanager切换的常见缘由。
(1) resourcemanager进程挂掉;(人为杀死,系统故障,resourcemanager产生致命异常等)
(2) resourcemanager和zookeeper链接超时;(网络故障等)
(3)手工切换
Ha切换对集群的影响:
(1)切换过程当中yarn服务没法访问
(2)rm切换会致使任务状态的从新加载(从zookeeper中读取任务状态),container级别的进度没办法恢复只能重跑,会致使任务的稍微延迟。