hadoop 工做上的一些知识点总结

HDFS部分java

  • 若是让你来运营一个hdfs集群,你会重点关注哪些性能指标?请说出缘由

详情参考hadoop相关性能指标说明。这里列出一些hdfs的关键指标node

(1)rpc相关shell

rpc.rpc.RpcQueueTimeAvgTimerpc平均队列时长apache

rpc.rpc.RpcProcessingTimeAvgTimerpc平均处理时长api

rpc.rpc.CallQueueLengthrpc队列请求队列长度安全

rpc.rpc.NumOpenConnections:rpc链接数网络

直接反应rpc性能的指标,若是出现明显增多,则说明namenode的性能异常。架构

 

(2)jvm相关并发

jvm.JvmMetrics.MemHeapUsedMjvm使用堆内存大小app

jvm.JvmMetrics.MemNonHeapUsedM jvm非堆内存使用大小

jvm.JvmMetrics.ThreadsBlocked:阻塞的线程数

jvm.JvmMetrics.ThreadsWaiting:无限期等待线程数

jvm.JvmMetrics.ThreadsTimedWaiting:等待线程数

 

(3)namespace相关

TotalFiles:总的文件数量

TotalBlocks:总的block数量

PercentUsed:集群hdfs使用百分比

BlockPoolUsedSpace:集群该namespacehdfs使用容量大小

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),有两个关键服务HealthMonitorActiveStandbyElector

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切换的常见缘由

  1. zkfc进程挂掉;(人为杀死,系统故障等)
  2. zkfc和zookeeper链接超时;(网络故障,zkfc持续full gc等)
  3. zkfcHealthMonitor检测到namenode故障,须要进行切换;(namenode自身故障,健康检测rpc请求超时,网络故障等等)

HAServiceProtocol协议的两个方法:getServiceStatus和monitorHealth

  1. 手工切换

 

Ha切换对集群的影响:

  1. 切换过程当中对hdfs服务没法访问
  2. 若是切换先后均是一主一从正常运行。要根据客户端对namenode访问顺序的配置和namenode负载分别分析。

示例:若是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之间主要作了以下工做:

  1. 新建一个RMAppAttemptImpl,并给他一个Start信号。
  2. 接下来就进入了RMAppAttemptImpl的生命周期。从NEW一直到LAUNCHED状态。
  3. RMAppAttemptImpl运行到LAUNCHED状态时会向RMApp回传ATTEMPT_REGISTERED事件,而后RMApp才会进入到RUNNING状态。

其中RMAppAttemptImpl从NEW到LAUNCHED之间主要作了以下工做:

  1. RMAppAttemptImpl向resourcemanager进行注册,调用ApplicationMasterProtocol的registerApplicationMaster方法
  2. RMAppAttemptImpl向调度器申请资源
  3. 调度器分配资源以后,会根据资源状况生成RMContainerImpl实例,并准备运行

其中

若是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级别的进度没办法恢复只能重跑,会致使任务的稍微延迟。

  1. 若是切换先后均是一主一从正常运行。要根据客户端对resourcemanager访问顺序的配置和namenode负载分别分析,同namenode。
相关文章
相关标签/搜索