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級別的進度沒辦法恢復只能重跑,會致使任務的稍微延遲。