1、巡檢
YARN 為 Hadoop 集群的上層應用,包括 MapReduce、Spark 等計算服務在內,提供了統一的資源管理和調度服務。
每日早晚巡檢YARN 服務,主要檢查資源池內主機的健康狀態,保障 YARN 服務可用性。
1.1、YARN CM 運行狀態
Yarn 集群,目前 Cloudera Manager 顯示 6 個不良,16 個存在隱患
打開顯示為不良的 NodeManager,這個節點有壞盤正在報修階段
查看存在隱患的 NodeManager
查看正在運行的 Container 與總核數的差距
查看是否有大量失敗的 Container,目前很少
查看 resourcemanager 高可用狀態,良好
查看 resourcemanager 監控指標,內存充足,待定的 Container 持續負載不高
JVM 堆棧,沒有異常
查看內存、磁盤情況,內存充足,磁盤延遲低
1.2、YARN WEB UI 運行狀態
查看集群整體情況,發現 5 個 LOST 節點,1 個不健康節點
1 個不健康節點是有壞盤情況,已經進去報修階段
5 個 Lost Nodes 是因為幾個主機總是出問題以及 IAAS 測正在查看
查看資源隊列資源使用情況,因為我是晚上 8 點截的圖,是低峰期,所以使用資源不多
1.3、YARN/MR 關鍵性能指標
各個 NodeManager 的 GC 時間
gc 時間基本在幾 ms,gc 正常。
NodeManager 駐留內存
NodeManager 駐留內存為 1G 左右,因此建議提升 NodeManager 內存。
集群每秒完成的任務數
每秒完成 1.5 個任務。
1.3.1、存在問題
集群資源使用率較低
集群節點內存使用,節點普遍內存使用都只有 10G 左右。
集群節點 CPU 平均使用率在 40%左右,不算很高。
但是從 Yarn 的頁面可以看到,Yarn 的集群使用率已經高達 100%
1.3.2、原因分析
Yarn 顯示資源使用率達到 100%,而集群節點內存,CPU 等資源卻使用不是很高。
Yarn 在配置時,通過設定每個 NodeManager 可以分配的 Container 內存, 以及 CPU,來設定每個節點的資源。目前每個 NodeManager 配置了 120G,CPU 配置了 32VCore。
目前集群可能存在的問題是,每個 Container 分配的資源過高,實際任務並不需要這么多資源,從而出現了資源被分配完,但是使用率低的情況。
1.3.3、建議方案
降低 Container 的內存分配,增加 Nodemanager 能夠分配的 Vcore 數。配置如下:
1.Container 虛擬 CPU 內核yarn.nodemanager.resource.cpu-vcores: 48
2.Map 任務內存 mapreduce.map.memory: 1.5G
3.Reduce 任務內存 mapreduce.reduce.memory.mb 1.5G
4.Map 任務最大堆棧 mapreduce.map.java.opts.max.heap 1.2G
5.Reduce 任務最大堆棧 mapreduce.reduce.java.opts.max.heap 1.2G 不過注意,對於某些對於內存需求較高的任務,需要單獨設定,保證不出現outofmemory 的情況。
2、參數調優
2.1、節點內存資源
yarn.nodemanager.resource.memory-mb
NodeManager 一般和 datanode 部署在一起,這些角色本身也要消耗內存, 並且操作系統也需要部分內存,建議 Container 內存可以適當降低,這些總的內存相加不能超過節點物理內存,我們給操作系統留 5G 以內的內存
2.2、節點虛擬 CPU 內核
yarn.nodemanager.resource.cpu-vcores
NodeManager 可以使用的核數,我們產線環境的核數配置的跟機器的核數是一致的
2.3、Container 最小分配內存
yarn.scheduler.minimum-allocation-mb
Container 最小內存定義了 Yarn 可以分配給 Container 最小資源,不管任務本身處理的數據量大小,都會至少分配這么多的內存,我們產線環境設置的是2G,從目前的監控上看內存資源是夠用的,CPU 資源緊張
2.4、Container 最大分配內存
yarn.scheduler.maximum-allocation-mb
Container 最大可申請的內存,目前我們產線環境配置的是 32G,因為我們產線環境有 Spark 作業,Spark 同一個執行器可以跑多個任務,平分內存
2.5、資源規整化因子
yarn.scheduler.increment-allocation-mb 假如規整化因子 b=512M,上述講的參數
yarn.scheduler.minimum-allocation-mb 為 1024, yarn.scheduler.maximum-allocation-mb 為 8096,然后我打算給單個 map 任務申請內存資源(mapreduce.map.memory.mb):
申請的資源為 a=1000M 時,實際 Container 最小內存大小為 1024M(小於yarn.scheduler.minimum-allocation-mb 的話自動設置為yarn.scheduler.minimum-allocation-mb);
申請的資源為 a=1500M 時,實際得到的 Container 內存大小為 1536M,計算公式為:ceiling(a/b)*b,即 ceiling(a/b)=ceiling(1500/512)=3,
3*512=1536。此處假如 b=1024,則 Container 實際內存大小為 2048M 也就是說 Container 實際內存大小最小為
yarn.scheduler.minimum-allocation-mb 值,然后增加時的最小增加量為規整化因子 b,最大不超過 yarn.scheduler.maximum-allocation-mb
當使用 capacity scheduler 或者 fifo scheduler 時,規整化因子指的就是參數yarn.scheduler.minimum-allocation-mb,不能單獨配置,即yarn.scheduler.increment-allocation-mb 無作用;
當使用 fair scheduler 時,規整化因子指的是參數yarn.scheduler.increment-allocation-mb
我們產線環境設置的是 512M
2.6、Container 最小虛擬 CPU 內核數量
yarn.scheduler.minimum-allocation-vcores 產線環境配置的為 1
2.7、最大Container 虛擬 CPU 內核數量
yarn.scheduler.maximum-allocation-vcores 我們的產線環境配置的是 12
2.8、MapReduce ApplicationMaster 的內存
yarn.app.mapreduce.am.resource.mb
我們產線環境設置的是 2G,2G 基本夠用了,如果有特殊情況,可以酌情改大
2.9、ApplicationMaster Java 最大堆棧
通常是 yarn.app.mapreduce.am.resource.mb 的 80%,1.6G
2.10、Map 任務內存
mapreduce.map.memory.mb
Map 任務申請的內存大小,產線環境設置的是 2G,一般有作業覆蓋
2.11、Reduce 任務內存
mapreduce.reduce.memory.mb
Reduce 任務申請的內容大小,產線環境設置的是 2G,一般有作業覆蓋
2.12、Map 和Reduce 堆棧內存
mapreduce.map.java.opts、mapreduce.reduce.java.opts
以 map 任務為例,Container 其實就是在執行一個腳本文件,而腳本文件中, 會執行一個 Java 的子進程,這個子進程就是真正的 Map Task,mapreduce.map.java.opts 其實就是啟動 JVM 虛擬機時,傳遞給虛擬機的啟動參數,表示這個 Java 程序可以使用的最大堆內存數,一旦超過這個大小,JVM 就會拋出 Out of Memory 異常,並終止進程。而mapreduce.map.memory.mb 設置的是 Container 的內存上限,這個參數由 NodeManager 讀取並進行控制,當 Container 的內存大小超過了這個參數值,NodeManager 會負責 kill 掉 Container。在后面分析yarn.nodemanager.vmem-pmem-ratio 這個參數的時候,會講解NodeManager 監控 Container 內存(包括虛擬內存和物理內存)及 kill 掉Container 的過程。就是說,mapreduce.map.java.opts 一定要小於mapreduce.map.memory.mbmapreduce.reduce.java.opts 同 mapreduce.map.java.opts 一樣的道理。默認是 mapreduce.map.memory.mb 和 mapreduce.reduce.memory.mb 的 80%
2.13、ResourceManager 的 Java 堆棧大小
產線環境配置的是 32G,-Xmx32768m 產線環境使用了 16G
2.14、NodeManager 的 Java 堆棧大小
產線環境配置的是 1G,-Xmx1024m
對於節點數較大,並且處理任務較多的集群,NodeManager 的內存可以相應設置的充裕一些,比如 2G-4G
2.15、Reduce 任務前要完成的 Map 任務數量
mapreduce.job.reduce.slowstart.completedmaps
該參數決定了 Map 階段完成多少比例之后,開始進行 Reduce 階段,如果集群空閑資源較多,該參數可以設置的比較小,如果資源緊張,建議可以設置的更大,由 0.8 改為 0.95
2.16、Hive 參數匯總
1.組合參數優化:減少 map 數
是否支持可切分的CombineInputFormat 合並輸入小文件此參數必須加否則不生效
set hive.hadoop.supports.splittable.combineinputformat=true;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFor mat;
一個節點上 split 的至少的大小
set mapred.max.split.size=1073741824;
一個交換機下 split 至少的大小
set mapred.min.split.size.per.node=1073741824;
2.組合參數優化:調整 reduce 輸出大小,降低 reduce 數,降低小文件輸出
強制指定 reduce 的任務數量,可以設置這個參數,如果不確定忽略此參數, 用下面的兩個參數
mapred.reduce.tasks=${num}
reduce 最大個數
set hive.exec.reduceRegionServer.max=300;
每個 reduce 任務處理的數據量,一般設置為 2G, 2G = 2147483648 Bytes
set hive.exec.reduceRegionServer.bytes.per.reducer=2147483648;
hive.exec.reduceRegionServer.bytes.per.reducer 67108864 默認值是64M
3.優化小文件問題
在 Map-only 的任務結束時啟用合並小文件set hive.merge.mapfiles=true;
在 Map-Reduce 的任務結束時啟用合並小文件set hive.merge.mapredfiles=true;
當輸出文件的平均大小小於該值時,啟動一個獨立的 map-reduce 任務進行文件 merge
set hive.merge.smallfiles.avgsize=1073741824;
合並后文件的大小為 1GB 左右
set hive.merge.size.per.task=1073741824;
4.container 內存大小
map 內存
set mapreduce.map.memory.mb=2048; 集群最小值是 2048M,與
mapreduce.map.memory.mb/mapred.max.split.size 比例是 2:1
reduce
set mapreduce.reduce.memory.mb=4096;與hive.exec.reduceRegionServer.bytes.per.reducer 參數比例 1:1~1:2
set mapred.child.java.opts=-Xmx3481m;確認集群與 mapreduce.map.memory.mb 的關系
5.作業通用參數
job 名
set mapreduce.job.name=P_DWA_D_IA_test;
隊列名
set mapreduce.job.queuename=ia;
3、運維
3.1、運維命令
3.1.1、application
yarn application [options]
-list
#列出 RM 中的應用程序。支持使用-appTypes 來根據應用程序類型過濾應用程序,並支持使用-appStates 來根據應用程序狀態過濾應用程序。
-kill <ApplicationId>
#終止應用程序。
-status <ApplicationId>
#打印應用程序的狀態。
-appStates <States>
#與-list 一起使用,可根據輸入的逗號分隔的應用程序狀態列表來過濾應用程序。有效的應用程序狀態可以是以下之一: ALL,NEW,NEW_SAVING,SUBMITTED,ACCEPTED,RUNNING, FINISHED,FAILED,KILLED
-appTypes <Types>
#與-list 一起使用,可以根據輸入的逗號分隔的應用程序類型列表來過濾應用程序。
3.1.2、applicationattempt
yarn applicationattempt [options]
-help #幫助
-list <ApplicationId> #獲取到應用程序嘗試的列表,其返回值ApplicationAttempt-Id 等於 <Application Attempt Id>
-status <Application Attempt Id> #打印應用程序嘗試的狀態。
3.1.3、classpath
yarn classpath
#打印需要得到 Hadoop 的 jar 和所需要的 lib 包路徑
3.1.4、container
yarn container [options]
#打印 container(s)的報告
-help #幫助
-list <Application Attempt Id> #應用程序嘗試的ContaineRegionServer 列表
-status <ContainerId> #打印 Container 的狀態
3.1.5、logs
yarn logs -applicationId <application ID> [options] #轉存container 的日志。
復制代碼
-applicationId <application ID> #指定應用程序 ID,應用程序的 ID 可以在 yarn.resourcemanager.webapp.address 配置的路徑查看(即:ID)
-appOwner <AppOwner> #應用的所有者(如果沒有指定就是當前用戶)應用程序的 ID 可以在 yarn.resourcemanager.webapp.address 配置的路徑查看(即:User)
-containerId <ContainerId> #Container Id
-help #幫助
-nodeAddress <NodeAddress> # 節點地址的格式:nodename:port(端口是配置文件中:yarn.nodemanager.webapp.address 參數指定)
3.1.6、node
yarn node [options]
#打印節點報告
-all #所有的節點,不管是什么狀態的。
-list #列出所有 RUNNING 狀態的節點。支持-states 選項過濾指定的狀態,節點的狀態包含:NEW,RUNNING,UNHEALTHY,DECOMMISSIONED,LOST,REBOOTED。支持--all 顯示所有的節點。
-states <States> #和-list 配合使用,用逗號分隔節點狀態,只顯示這些狀態的節點信息。
-status <NodeId> #打印指定節點的狀態。
3.1.7、queue
yarn queue [options]
#打印隊列信息
-status #<QueueName> 打印隊列的狀態
3.1.8、rmadmin
yarn rmadmin [-refreshQueues]
[-refreshNodes]
[-refreshUserToGroupsMapping]
[-refreshSuperUserGroupsConfiguration] [-refreshAdminAcls]
[-refreshServiceAcl]
[-getGroups [username]]
<serviceId>]
<serviceId2>]
[-transitionToActive [--forceactive] [--forcemanual]
[-transitionToStandby [--forcemanual] <serviceId>] [-failover [--forcefence] [--forceactive] <serviceId1>
[-getServiceState <serviceId>] [-checkHealth <serviceId>]
[-help [cmd]]
-refreshQueues #重載隊列的 ACL,狀態和調度器特定的屬性,ResourceManager 將重載 mapred-queues 配置文件
-refreshNodes #動態刷新 dfs.hosts 和 dfs.hosts.exclude 配置,無需重啟 ResourceManager。
#dfs.hosts:列出了允許連入 NameNode 的 datanode 清單(IP 或者機器名)
#dfs.hosts.exclude:列出了禁止連入 NameNode 的datanode 清單(IP 或者機器名)
#重新讀取 hosts 和 exclude 文件,更新允許連到Namenode 的或那些需要退出或入編的 datanode 的集合。
-refreshUserToGroupsMappings #刷新用戶到組的映射。
-refreshSuperUserGroupsConfiguration #刷新用戶組的配置
-refreshAdminAcls #刷新 ResourceManager 的ACL 管理
-refreshServiceAcl #ResourceManager 重載服務級別的授權文件。
-getGroups [username] #獲取指定用戶所屬的組。
-transitionToActive [–forceactive] [–forcemanual] <serviceId> #嘗試將目標服務轉為 Active 狀態。如果使用了–forceactive 選項,不需要核對非Active 節點。如果采用了自動故障轉移,這個命令不能使用。雖然你可以重寫
–forcemanual 選項,你需要謹慎。
-transitionToStandby [–forcemanual] <serviceId> # 將服務轉為 Standby 狀態. 如果采用了自動故障轉移,這個命令不能使用。雖然你可以重寫–forcemanual 選項,你需要謹慎。
-failover [–forceactive] <serviceId1> <serviceId2> # 啟 動 從 serviceId1 到 serviceId2 的故障轉移。如果使用了-forceactive 選項,即使服務沒有准備, 也會嘗試故障轉移到目標服務。如果采用了自動故障轉移,這個命令不能使用。
-getServiceState <serviceId> #返回服務的狀態。(注:ResourceManager 不是 HA 的時候,是不能運行該命令的)
-checkHealth <serviceId> #請求服務器執行健康檢查,如果檢查失敗,RMAdmin 將用一個非零標示退出。(注:ResourceManager 不是 HA 的時候,是不能運行該命令的)
-help [cmd] #顯示指定命令的幫助,如果沒有指定,則顯示命令的幫助。
3.2、啟動、停止
3.2.1、命令行啟動
1.全部啟動 YARN 集群
./bin/start-yarn.sh
2.全部停止 YARN 集群
./bin/stop-yarn.sh
3單獨啟停 resourcemanager 集群
./bin/yarn-deamon.sh start resourcemanager
./bin/yarn-deamon.sh stop resourcemanager
4單獨啟停 nodemanager 集群
./bin/yarn-deamon.sh start nodemanager
./bin/yarn-deamon.sh stop nodemanager
3.2.2、CM啟動、停止
1.整體啟動、停止、重啟、滾動重啟
2.部分啟動、停止、重啟、滾動重啟
3.3、擴縮容
同HDFS擴縮容
3.4、資源隊列-容量調度
3.4.1、概述
Hadoop 的可插拔調度器,允許多租戶安全地共享一個大集群,以便在分配容量的約束下及時為應用程序分配資源,被設計來以共享、多租戶的形式運行hadoop 應用程序,在友好規則下,能夠更大限度地提高集群的吞 吐量和利用率。
Capacity Schedule 調度器以隊列為單位划分資源。簡單通俗點來說,就是一個個隊列有獨立的資源, 隊列的結構和資源是可以進行配置的。
default 隊列占 30%資源,analyst 和 dev 分別占 40%和 30%資源;類似的,analyst 和 dev 各有兩個子隊列,子隊列在父隊列的基礎上再分配資源。隊列以分層方式組織資源,設計了多層級別的資源限制條件以更好的讓多用戶共享一個 Hadoop 集群,比如隊列資源限制、用戶資源限制、用戶應用程序數目限制。隊列里的應用以 FIFO 方式調度,每個隊列可設定一定比例的資源最低保證和使用上限,同時每個用戶也可以設定一定的資源使用上限以防止資源 濫用。而當一個隊列的資源有剩余時,可暫時將剩余資源共享給其他隊列。
3.4.2、特性
1.分層隊列
支持層級隊列來確保資源在子隊列間共享。
2.容量保證
所有提交到隊列的的應用程序都將能保證獲取到資源,管理員可以配置soft 和硬件資源分配到每個隊列的限制。
3.安全性
每個隊列有嚴格的 ACLs 權限控制,允許哪些用戶提交到某個隊列,哪些用戶不能看看或者修改其他人的應用等。
4.彈性
彈性特性允許閑置資源能被任何隊列分配到。
5.多租戶
一系列全面的限制,防止單個應用程序、單用戶和隊列獨占隊列或集群的所有資源,以確保集群不會不堪重負。
6.可操作性
運行時配置:運行時可以配置隊列的定義、屬性修改等操作,比如容量、acl 修改
作業保障:管理員停止隊列時,保障正在運行的應用程序運行完成,保障其他新的應用程序不能提交到 隊列或者子隊列。
3.4.3、調度器設置
要配置 ResourceManager 以使用 CapacityScheduler,請在 conf/yarn-site.xml 中 設 置 以 下 屬 性 : yarn.resourcemanager.scheduler.class:org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.C apacityScheduler
CM 中設置:
3.4.4、隊列參數
1.資源分配相關參數:
capacity:隊列的最小資源容量(百分比)。注意,所有隊列的容量之和應小於 100
maximum-capacity:隊列的資源使用上限
minimum-user-limit-percent:每個用戶最低資源保障(百分比)
user-limit-factor:每個用戶最多可使用的資源量(百分比)
2.限制應用程序數目的相關參數:
maximum-applications:集群或者隊列中處於等待和運行狀態的應用程序數目上限,這是一個強限制項,一旦集群中應用程序數目超過該上限, 后續提交的應用程序將被拒絕。默認值為 10000。Hadoop 允許從集群和隊列兩個方面該值,其中,集群的總體數目上限可通過參數yarn.scheduler.capacity.maximum-applications 設置,默認為 10000, 而單個隊列可通過參數yarn.scheduler.capacity.<queue-path>.maximum-applications 設置適合自己的值
maximum-am-resource-percent:集群中用於運行應用程序ApplicationMaster 的資源比例上限,該參數通常用於限制處於活動狀態的應用程序數目。所有隊列的 ApplicationMaster 資源比例上限可通過參數 yarn.scheduler.capacity.maximum-am-resource-percent 設置,而單個隊列可通過參數yarn.scheduler.capacity.<queue-path>.maximum-am-resource-percent 設置適合自己的值
3.隊列訪問權限控制
state:隊列狀態,可以為 STOPPED 或者 RUNNING。如果一個隊列處於 STOPPED 狀態,用戶不可以將應用程序提交到該隊列或者它的子隊列中。類似的,如果 root 隊列處於 STOPPED 狀態,則用戶不可以向集群提交應用程序,但正在運行的應用程序可以正常運行結束,以便隊列可以優雅地退出
acl_submit_application:限定哪些用戶/用戶組可向給定隊列中提交應用程序。該屬性具有繼承性,即如果一個用戶可以向某個隊列提交應用程序,則它可以向它所有子隊列中提交應用程序
acl_administer_queue:為隊列指定一個管理員,該管理員可控制該隊列的所有應用程序,比如殺死任意一個應用程序等。同樣,該屬性具有繼承性,如果一個用戶可以向某個隊列中提交應用程序,則它可以向它的所有子隊列中提交應用程序當管理員需動態修改隊列資源配置時,可修改配置文件conf/capacity-scheduler.xml,然后運行“yarn rmadmin -refreshQueues” 當前 Capacity Scheduler 不允許管理員動態減少隊列數目,且更新的配置參數值應是合法值,否則會導致配置文件加載失敗
3.4.5、隊列配置
CapacityScheduler 有一個預定義隊列叫 root,系統中所有的隊列是 root 隊列的一個子隊列。
更多的隊列可以通過配置 yarn.scheduler.capacity.root.queues 該屬性來配置,多個子隊列 使用","來分割。
CapacityScheduler 有一個概念叫 queue path,是用來配置隊列層級的,這個 queue path 是隊列的 層級,使用 root 開始,然后用"."來進行連接。比如root.a。
隊列的子隊列可使用 yarn.scheduler.capacity.<queue-path>.queues 來配置。除非另有申明,否則子元素不能直接從父元素繼承屬性。
產線案例
<?xml veRegionServerion="1.0" encoding="utf-8"?>
<configuration>
<property>
<name>yarn.scheduler.capacity.maximum-applications</name>
<value>10000</value>
</property>
<property>
<name>yarn.scheduler.capacity.resource-calculator</name>
<value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>default,ia,ia_dzh,ia_serv</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.capacity</name>
<value>0</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.user-limit-factor</name>
<value>1</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
<value>100</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.state</name>
<value>RUNNING</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.acl_submit_applications</name>
<value>t1</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.acl_administer_queue</name>
<value>t1</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia.capacity</name>
<value>50</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia.user-limit-factor</name>
<value>2</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia.maximum-capacity</name>
<value>100</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia.state</name>
<value>RUNNING</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia.acl_submit_applications</name>
<value>if_ia_pro,if_ia_serv</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia.acl_administer_queue</name>
<value>ia</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_dzh.capacity</name>
<value>30</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_dzh.user-limit-factor</name>
<value>5</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_dzh.maximum-capacity</name>
<value>100</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_dzh.state</name>
<value>RUNNING</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_dzh.acl_submit_applications</name>
<value>if_ia_pro</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_dzh.acl_administer_queue</name>
<value>if_ia_pro</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_serv.capacity</name>
<value>20</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_serv.user-limit-factor</name>
<value>4</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_serv.maximum-capacity</name>
<value>100</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_serv.state</name>
<value>RUNNING</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_serv.acl_submit_applications</name>
<value>lf_ia_serv</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.ia_serv.acl_administer_queue</name>
<value>ia_serv</value>
</property>
</configuration>
3.5、資源隊列-公平調度設置
3.5.1、概述
公平調度是一種為應用程序分配資源的方法,它可以隨時間使得所有應用程序平均獲得相等的資源份額。 下一代的 Hadoop 能夠調度多種資源類型。默認情況下,公平調度程序僅基於內存來確定調度公平性決策。它可以使用Ghodsi 等人開發的DRF(作業調度算法)的概念來配置,同時調度內存和 CPU。當有一個應用程序在運行時,該應用程序將使用整個集群。當提交其他應用程序時,將會有資源被釋放來分配給新應用程序,以便最終每個應用程序獲得的資源大致相同。與組成應用程序隊列的默認 Hadoop 調度器不同,這可以讓短應用程序在合理的時間內完成,同時不會使長期存在的應用程序挨餓。它也是一種在多個用戶之間共享群集的合理方式。最后,公平共享還可以與應用優先級一起使用 - 優先級用權重來確定每個應用應獲得的總資源的比例。
調度程序將應用程序進一步組織為“隊列”,並在這些隊列之間公平地共享資源。默認情況下,所有用戶共享一個名為“default”的隊列。如果應用程序專門在容器資源請求中列出隊列,則將請求提交給該隊列。還可以通過配置中基於請求的用戶名來分配隊列。在每個隊列中,調度策略被用來在正在運行的應用程序之間共享資源。默認是根據內存來公平分享資源,但也可以配置具有 DRF(作業調度算法)的 FIFO 和多資源策略。隊列可以按照階級來划分資源,並根據權重配置來按特定比例去共享群集。
除了提供公平共享資源外,Fair Scheduler 還允許為隊列分配可保證的最小資源,這對於確保某些用戶,用戶組或生產應用始終獲得足夠的資源是很有用的。當隊列包含應用程序時,它最少能獲得一個最小資源,但是當隊列不需要完全保證共享時,超出部分將在其他正在運行的應用程序之間分配。這使得調度器可以保證隊列容量,同時在隊列里不包含應用程序時,可以有效地利用資源。
Fair Scheduler 允許所有應用程序默認運行,但也可以通過配置文件限制每個用戶和每個隊列運行的應用程序數量。這在當用戶必須一次提交數百個應用程序時是非常有用的,或者說,如果同時運行太多應用程序會導致創建過多的中間數據或過多的上下文切換時,可以提高性能。限制應用程序不會導致任何后續提交的應用程序失敗,只會在調度程序的隊列中等待,直到某些用戶的早期的應用程序完成為止。
3.5.2、具有可插拔策略的分層隊列
Fair Scheduler 支持層次隊列(hierarchical queues),所有隊列都從 root隊列開始,root 隊列的孩子隊列公平地共享可用的資源。孩子隊列再把可用資源公平地分配給他們的孩子隊列。apps 可能只會在葉子隊列被調度。此外, 用戶可以為每個隊列設置不同的共享資源的策略,內置的隊列策略包括 FifoPolicy, FaiRegionServerharePolicy (default), and DominantResourceFairnessPolicy。
3.5.3、隊列配置
自定義 Fair Scheduler 通常涉及更改兩個文件。首先,可以通過在現有配置目錄的 yarn-site.xml 文件中添加配置屬性來設置調度程序范圍的選項。其次,在大多數情況下,用戶需要創建一個分配文件,列出存在哪些隊列以及它們各自的權重和容量。分配文件每 10 秒重新加載一次,允許動態更改。
可以放在 yarn-site.xml 中的屬性屬性描述
yarn.scheduler.fair.allocation.file分配文件的路徑。除了某些策略默認值之外,分配文件是描述隊列及其屬性的 XML 清單。此文件必須采用下一節中描述的 XML 格式。如果給出了相對路徑,則在類路徑(通常包括 Hadoop conf 目錄)上搜索文件。默認為 fair-scheduler.xml。
yarn.scheduler.fair.user-as-default-queue 在未指定隊列名稱的情況下,是否將與分配關聯的用戶名用作缺省隊列名稱。如果將其設置為“false”或未設置,則所有作業都有一個共享的默認隊列,名為“default”。默認為 true, 產線環境一版會置位 false
yarn.scheduler.fair.preemption 是否使用搶占。默認為 true。分配文件必須是 XML 格式。格式包含五種類型的元素:
Queue elements:代表隊列。隊列元素可以采用可選屬性“類型”,當設置為“父”時,它將使其成為父隊列。當我們想要創建父隊列而不配置任何葉隊列時,這非常有用。每個隊列元素可能包含以下屬性:
minResources: 隊 列 有 權 獲 得 的 最 小 資 源
maxResources: 分 配 隊 列 的 最 大 資 源
maxRunningApps: 限 制 隊 列 中 的 應 用 程 序 數 量 一 次 運 行
maxAMShare:限制可用於運行應用程序主服務器的隊列公平共享的分數。
weight:與其他隊列不成比例地共享群集。權重默認為 1,權重為 2 的隊列應該獲 得 的 資 源 大 約 是 具 有 默 認 權 重 的 隊 列 的 兩 倍 。
schedulingPolicy:設置任意隊列的調度策略。
aclSubmitApps:可以將應用程序提交到隊列的用戶和/或組的列表。
aclAdministerApps:可以管理隊列的用戶和/或組的列表。
3.5.4、隊列設置
1.設置 yarn.resourcemanager.scheduler.class 值為org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FaiRegi onServercheduler
3.5.5、Web UI 監控
可以通過 ResourceManager 的 Web 界面在 http://*ResourceManagerURL*/cluster/scheduler 中檢查當前的應用程序,隊列和公平份額(資源)。
可以在 Web 界面上的每個隊列中看到以下字段: Used Resources - 分配給隊列中容器的資源總和。
Num Active Applications - 隊列中至少收到一個容器的應用程序數。Num Pending Applications - 隊列中尚未收到任何容器的應用程序數。Min Resources - 保證隊列的最低資源配置。
Max Resources - 允許進入隊列的最大資源配置。
Instantaneous Fair Share - 隊列的瞬時公平份額資源。這些資源僅考慮活動隊列(具有正在運行的應用程序的隊列),並用於調度決策。當其他隊列不使
用隊列時,可以為隊列分配超出其共享的資源。資源消耗等於或低於其瞬時公平份額的隊列將永遠不會搶占其容器。
Steady Fair Share - 隊列穩定的公平份額資源。這些資源考慮所有隊列,無論它們是否處於活動狀態(已運行應用程序)。這樣,計算就不會很頻繁,而且僅在配置或容量發生變化時才會更改。它們旨在提供用戶可以預期的資源可見性,從而顯示在 Web UI 中。
3.6、資源隊列原則
3.7、資源隊列調整案例
【案例】
xx集群上的隊列分為生產型和非生產型。在xx日凌晨0 點--早上 9 點,非生產型隊列占用資源較多,導致集群壓力過大,影響了當日早上 9 點的 xx 下發。生產側提出了隊列資源的優化方案,如下:
Queue Absolute Capacity Configured Max Capacity
ds 2 3
ec 5 7
db_ser 3 2
hc 80 1.23
default 2 7
zy_scp 5 4
Am1c 3 4
【備份當前隊列的配置文件】
在 CM 首頁點擊 yarn
在 yarn 的【配置】頁面,搜索“容量調度”,調出右側的【值】
將【值】中的數據全部復制出來備份到本地。建議粘貼到寫字板上,粘貼到 txt 里排版會出現混亂。
【修改當前隊列的配置信息】
以 qc 隊列為例:
【保存更改】
【刷新動態資源池】
在 CM 首頁,點擊集群右邊的倒三角,再點擊【刷新動態資源池】
【核實已經修改成功】
在 Applications 頁面的 Scheduler,調出 qc 隊列的信息
3.8、無CM 修改隊列資源
【需求】
固網集群 xx 隊列 lf_zl 資源 38%*1.8 拆分
原隊列 lf_zl 改為 25%*2 租戶使用
其余資源新增隊列 lf_ja 13%*1.8 預計后續部署租戶使用
【修 改 capacity-scheduler.xml 】
cd/opt/beh/core/hadoop/etc/hadoop/ #進入配置文件所在目錄cpcapacity-scheduler.xmlcapacity-scheduler.xml_20170616 #備份配置文件
vi capacity-scheduler.xml #修改配置文件
修改 yarn.scheduler.capacity.root.queues 的值,在 value 里添加 lf_ja
修改原 lf_zl 的值:
把 yarn.scheduler.capacity.root.lf_zl.capacity 的值從 38 改為 25
把 yarn.scheduler.capacity.root.lf_zl.user-limit-facto 的值從 1.8 改為 2
在配置文件中新增隊列配置文件,如下:
<property>
<name>yarn.scheduler.capacity.root.lf_ja.capacity</name>
<value>13</value>
<description>default queue target capacity.</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.lf_ja.user-limit-factor</na me>
<value>1.8</value>
<description>
default queue user limit a percentage from 0.0 to 1.0.
</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.lf_ja.maximum-capacity</ name>
<value>100</value>
<description>
The maximum capacity of the default queue.
</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.lf_ja.state</name>
<value>RUNNING</value>
<description>
The state of the default queue. State can be one of RUNNING or STOPPED.
</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.lf_ja.acl_submit_applicatio ns</name>
<value>lf_ja_pro</value>
<description>
The ACL of who can submit jobs to the default queue.
</description>
</property>
<property>
<name>yarn.scheduler.capacity.root.lf_ja.acl_administer_queue
</name>
<value>lf_ja_pro</value>
<description>
The ACL of who can administer jobs on the default
queue.
</description>
</property>
【把更改后的配置文件拷貝到 stanby 節點】
cp /opt/beh/core/hadoop/etc/hadoop/capacity-scheduler.xml /opt/beh/core/hadoop/etc/hadoop/capacity-scheduler.xml_20170616#登錄 stanby 節點備份原配置文件
scp /opt/beh/core/hadoop/etc/hadoop/capacity-scheduler.xml hadoop@10.162.3.71:/opt/beh/core/hadoop/etc/hadoop/capacity-scheduler.xml #把修改后的配置文件拷貝到備節點主機上
【登錄主節點動態刷新資源池】
yarn rmadmin -refreshQueues#刷新動態資源池
【登錄 yarn 界面檢查更改結果是否正確】
如圖:
3.9、修改用戶yarn 資源分配
hadoop修 改 用 戶yarn隊 列 分 配 倍 數
1.以管理員用戶登錄所要更改的 CM,進入后點擊 yarn,如圖:
2.在 yarn 界面點擊配置按鈕,並在彈出的查找框中輸入“容量調度”,查找如圖:
3.把出現的值粘貼到文本留作備份(建議粘貼到寫字板上,粘貼到 txt 里排版會出現混亂)切記一定要備份!!!
4.修改所需修改的值(一般限制用戶隊列,建議修改分配的倍數即 Configured User Limit Factor 這個值。修改 Absolute Capacity 需要對整體集群進行計算,所以用戶加一起的達到百分百,建議不做修改)
5.列:如修改 didi 用戶的 Configured User Limit Factor 值。
(1)登錄 yarn,點擊 Scheduler,點擊 didi 用戶的倒三角圖標:
我們可以看出 didi 用戶的 Configured User Limit Factor 值為 3, 即他可以使用超出他分配百分比的三倍。
(2)修改拷貝中的文本,查找 didi 配置文件那列:
(3)找到所需修改的值 Configured User Limit Factor。將倍數修改成需要調整后的值。
(3)把配置文件拷貝回 CM-yarn-配置-容量調度的那個文本框里,點擊保存。
(4)回到 CM 主頁,點擊集群右邊的倒三角,點擊刷新動態資源池。
(5)配置完畢,到 yarn 上查看修改是否成功。
4、排障
4.1、資源問題
【現象】
目前 CC 集群出現大量任務積壓,運行緩慢的情況,懷疑是集群的資源分配出現了問題。
CC 集群總共有 569 個 NodeManager,總共 VCore 數是 27704 ,內存171T,資源比較豐富。理論上,應該足夠任務的執行。
經過現場的分析,發現如下現象。
集群總體的資源使用高,少量剩余
如下圖所示,集群總體的資源使用已經非常高,但是仍有少量剩余。其中 CPU Vcore,總共 27704 個,使用了 26842 個。內存總共 171T,使用了153T。即集群 CPU 使用了 95%以上,但是仍然有少量的剩余。
隊列最小資源沒有得到滿足
從上圖可以看出,目前配置的隊列最小資源都設置的比較大,即使集群資源使用非常高,仍然沒有滿足最小資源的需求。隊列最小資源,是集群有資源的情況下,必須要滿足的資源。並且集群中,絕大部分隊列都沒有達到最小資源。
出現大量 Map Pening
如下圖所示,集群中出現大量的任務都有如下的現象。Reduce 已經啟動, 在等待 Map 階段完成,然后向前執行,但是 Map 階段還有部分任務沒有完成, 這部分任務也拿不到資源執行,running 的 map 為 0。從而出現了死鎖的情況。即 Reduce 啟動了占用了資源,但是在等待 Map,而 Map 拿不到資源無法執行。
【分析】
根據上面的現象,可以分析得出,導致任務出現積壓的情況,直接原因是因為,出現了資源分配的死鎖。即 Reduce 階段占用了資源,但是需要等待Map 階段執行完成,而 Map 階段在等待資源,但是資源已經被 Reduce 都占用了,無法申請到資源,因此無法執行。大量的任務都出現了這種情況,集群中絕大部分的資源都被 Reduce 的 Container 占用了,而 Map 階段分到的資源很少。
Mapreduce 任務在執行任務時,分為 Map,Reduce 兩個階段,這兩個階段都需要申請 yarn 的 Container,進行運行。並且 Yarn 並不區分 Map,
Reduce 的 Container 類型,只要是申請資源,會一視同仁。Reduce 階段, 需要獲取 Map 階段的輸出,從而繼續往下執行。Yarn 通過參數
mapreduce.job.reduce.slowstart.completedmaps,設定比例,例如設置為0.8(目前集群設置為 0.8),則 Map 階段完成 80%后,Reduce 階段就會開始申請 Container,占用資源。提前啟動 Reduce 的好處是,可以盡早的申請到資源,然后 Reduce 首先從已經完成的 Map 任務中拷貝數據,Map 同時執行。從而,加快整體任務的執行。
然而,這個設定,在極端情況下,會出現問題:
1.集群中存在大量任務同時運行
2.其中不少的任務都需要啟動大量的 Map 任務和 reduce 任務
3.集群總體的資源使用率已經非常高,沒有很多的剩余資源
在上述的情況下,就有可能出現資源死鎖的情況。由於大量的任務同時運行,並且其中不少的任務都有大量的 Map 任務和 Reduce 任務,當 Map 任務完成到一定比例之和,就開始啟動 Reduce 任務,Reduce 任務啟動之后, 占用了資源,但是 Map 還沒有結束。集群總體的資源使用率已經非常高,沒有很多的剩余資源,Map 階段分配不到足夠的資源,只能非常緩慢的運行,或者甚至分不到資源,直接不運行了。
整個任務就停滯了,但是也不超時。
另外一個加劇該現象的原因是,因為目前集群隊列的資源設定中,每個資源池的最小資源占比設置的比較大,總和已經超過了集群資源的總和 。
設定隊列的最小資源,是為了保證隊列能夠至少能夠拿到最小資源,不至於被餓死。並且集群有一定的剩余資源,可以供資源池之間競爭,作為補充。但是目前的設定,導致即使集群所有的資源也無法滿足每個隊列的最小資源。這樣的情況,就導致了,集群的所有資源基本會被使用完,並且關鍵的是,所有的隊列都認為是自己的最小資源。即使某個隊列出現了資源飢餓的情況,也無法從集群或者其他隊列搶占部分資源來補充。
【解決方案】
設置 mapreduce.job.reduce.slowstart.completedmaps 為 1
設置為 1 之后,Reduce 需要等待 Map 階段都完成之后,才會申請資源並啟動,這樣的話,就不會出現 Reduce 占用資源而 Map 分配不到的情況了。
如下圖所示,通過 CM,設置mapreduce.job.reduce.slowstart.completedmaps 為 1。同時,原來設定默認 reduce 個數為 600, 這個值偏大,修改為 40。
重新調整資源池的設定
重新調整各資源池,最小資源,最大資源,以及並發任務數。
建議調整所有資源池的最小資源為集群資源的 60%。最大資源為集群資源的 100%。
【整體修改】
NodeManager 內存調整
如下圖所示,目前集群 NodeManager 內存為 2G,對於一個比較繁忙, 並且規模很大的集群,NodeManager 內存建議可以設置的稍微大一點,下圖修改成 4G。
【控制Map 數】
可以通過設置 mapreduce.input.fileinputformat.split.minsize 參數來控制任務的 Map 數,該參數控制每個 map 的最小處理數據量。
在 hive 中可以通過 set mapreduce.input.fileinputformat.split.minsize=67108864 來設置
4.2、慢作業
在 AA 集群中存在部分任務,執行較慢的情況。這些任務都是比較長的 hiveSQL,處理的數據量並不是很大,在幾個 G 左右,但是運行時間很長,需要 40 分鍾到一個小時。
經過分析,這些任務的 map 階段其實運行的很快,幾十秒就能結束,慢主要是發生在 Reduce 階段,Reduce 需要花費幾十分鍾才能運行完成。查看Reduce 階段日志發現,Reduce 寫出了大量的日志,約有 1G,並且這些日志都像是從表中獲取的數據進行的打印。正常 Hive 是不會輸出這些日志的,只有應用端進行了設置才會進行打印。
出現這種情況,最有可能的是使用 Java 代碼編寫了 Hive 的 UDF 程序,在UDF 中進行了打印,並且在 hive SQL 中使用了 UDF,從而打印了這些日志。經與生產側 xxx 溝通,確認使用了 UDF,應用正在確認相關代碼,並進行下一步解決。
4.3、gc overhead limit exceeded 導致map 失敗
【現象】
xx日,4m1-01 集群上的多個 job 執行失敗。
【定位失敗的 map task】
【查看失敗的 map tasks 的日志】
發現第 3 次 task attempt 有一條 FATAL 型的報錯: java.lang.OutOfMemoryError: GC overhead limit exceeded
【確認末端原因】
JVM 的堆棧過小,導致 job 執行失敗。
【解決辦法】
可以調整JVM的堆棧大小,但是目前沒有標准可供參考去調整JVM。而且這種報錯的頻率不高,所以只能建議業務方再多次執行 job,或改在資源較空閑的時間段執行 job。事實證明,這種辦法是可行的。
最佳方案:適當調大 mapreduce.map.memory.mb 這個參數的值
4.4、hive 執行任務中報內存不足的錯誤
執行 hive 前加上參數
set mapresuce.reduce.shuffle.input.buffer.percent=0.1;
set mapred.child.java.opts=-Xmx3096m; // jvm 啟動的子線程可以使用的最大內存
set mapreduce.reduce.shuffle.parallelcopies=10;// reuduce shuffle 階段並行傳輸數據的數量
export HADOOP_CLIENT_OPTS="-Xmx8192m $HADOOP_CLIENT_OPTS
4.5、Job 報錯失敗
用戶反映 JOB 執行失敗報錯,如下:
懷疑為沒有此目錄權限
查找該目錄下權限正常,但並無 mapred-audit.log 文件,其他接口機有此文件。
添加此文件:
4.6、NameNode RPC 負載過高
【現象】
基於小文件問題與 XXX 和 XXX 了解多租戶初篩程序問題,發現初篩程序 URLFilter_Hour_Tenants 在執行之前會獲取文件信息,獲取文件信息需要 2 至 5 小時才能完成。
【問題排查】
1、目前處理 HHH 日志的程序有如下: YX:凌晨 1 點分省處理昨天一天的數據
2、HHH 日志初篩,按小時處理省份數據,rpc 請求為 31 萬,缺點:每小時每個省份的作業處理卻要掃描當天此省份全量文件信息,造成大量無用的 rpc 請求
3、Spark streaming 實時采集原始日志,目前是增量獲取文件信息,對 rpc 的壓力影響較小
HHH 日志初篩現象:
Job 輸入目錄有 31 萬的文件,這個任務讀取整個文件夾其中的 1.4 萬的文件。如下截圖是初篩 job 的 rpc 請求,請求次數為 310172,從日志上看每秒鍾並發十幾次到幾十次,耗時 3 個半小時,並發度太低的原因是因為 rpc 請求隊列堆積了很多請求
昨天晚上 23 點到今天凌晨 2 點的時候,rpc 隊列累積請求長度較高
昨天晚上 23 點到今天凌晨 2 點的時候,rpc 平均請求時長偏高
【解決方案】
1、HHH 多租戶初篩程序由原來的 MR 批處理改為 spark streaming 實時采集處理,降低 rpc 負載,XXX 協助 XXX、XXX、XXX 改造程序
2、spark streaming 數據直接輸出到租戶對應目錄,省去 mv 環節
3、預計兩周上線,上線前需做代碼、流程評審
4.7、SRC 層分鍾表hive 入庫延遲排查
【現象】
XXLL 分鍾表 load 存在異常,平台支撐組牽頭排查 XXLLSRC 層分鍾表 hive 入庫延遲問題。
【問題排查】
Hive 錯誤日志
異常出現次數:大概 595 次
異常信息:
2019-04-27 01:38:41,484 ERROR ZooKeeperHiveLockManager (SessionState.java:printError(920)) - Unable to acquire IMPLICIT, EXCLUSIVE lock lf_xl_src@src_c_sa_basic_normal after 100 attempts. 2019-04-27 01:38:41,506 ERROR ql.Driver
(SessionState.java:printError(920)) - FAILED: Error in acquiring locks: Locks on the underlying objects cannot be acquired. retry after some time
org.apache.hadoop.hive.ql.lockmgr.LockException: Locks on the underlying objects cannot be acquired. retry after some time
at org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager.acquireLocks( DummyTxnManager.java:164)
at org.apache.hadoop.hive.ql.Driver.acquireLocksAndOpenTxn(Driver.java: 988)
at org.apache.hadoop.hive.ql.Driver.runInternal(Driver.java:1224) at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1053)
at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1043) at
org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver.java:20 9)
at org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:161) at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:372) at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:307) at org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:704) at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:677)
at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:617)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorI mpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethod AccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
Hive 鎖
查看鎖:
鎖擁有者:
> show locks src_c_sa_basic_normal extended;
OK
lf_xl_src@src_c_sa_basic_normal SHARED LOCK_QUERYID:lf_xl_bp_20190427164141_acb414ff-d237-414b-a778-5 ef916724c04
LOCK_TIME:1524818467680 LOCK_MODE:IMPLICIT
LOCK_QUERYSTRING:insert overwrite table lf_xl_dwd.dwd_d_sa_basic_n ormal_hour partition(month_id='201904',day_id='27',hour_id='15', prov_id='075',sa_type)
select msisdn , imsi ,
start_time , end_time , imei ,
mcc ,
mnc , current_lac, current_ci , roamtype , eventtype , rantype , province ,
fiRegionServert_lac , fiRegionServert_ci , latitude ,
longitude , area ,
hrov_id , harea_id, rmsisdn, rimsi, srvstat ,
cdRegionServertat ,
direction ,
srvorig ,
srvtype , poweroff_ind , csfb_res ,
enodebid , ci ,
destnet_type , sourcenet_type, uenc ,
msnc ,
res_time ,
msg_id , cause_code, district_id, hcountry, is_filled, recv_time, sa_type
from lf_xl_src.src_c_sa_basic_normal
where date_id='20190427' and hour_id='15' and prov_id='075' and no
t(imsi='' and msisdn='') and not(imsi regexp '\\D' or msisdn regexp '\\ D')
hive目前主要有兩種鎖,SHARED(共享鎖 S)和 Exclusive(排他鎖 X)。共享鎖 S 和 排他鎖 X 它們之間的兼容性矩陣關系如下:
Zookeeper 日志
Hive 獲取 lock 失敗:
日志條數:
Znode 結構:
進程堆棧:
進程堆棧信息:
"main" prio=10 tid=0x00007fdf7c012800 nid=0x772f waiting on condi tion [0x00007fdf85b23000]
java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method)
at org.apache.hadoop.hive.ql.lockmgr.zookeeper.ZooKeeperHiveL ockManager.lock(ZooKeeperHiveLockManager.java:268)
at org.apache.hadoop.hive.ql.lockmgr.zookeeper.ZooKeeperHiveL ockManager.lock(ZooKeeperHiveLockManager.java:182)
at org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager.acquir eLocks(DummyTxnManager.java:161)
at org.apache.hadoop.hive.ql.Driver.acquireLocksAndOpenTxn(Dri ver.java:988)
at org.apache.hadoop.hive.ql.Driver.runInternal(Driver.java:1224) at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1053)
at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1043)
at org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver. java:209)
at org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:161)
at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:372)
at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:307)
at org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:704)
at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:677) at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:617)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Delegating MethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
【目前解決方案】
取消 load 操作,改為 cp 操作,檢測 hdfs 文件修復 hive 分區。
【其他問題】
強制殺死 kafka 消費者:
每秒中周期提交 offset
4.8、大數據作業JVM 內存崩潰 1
【現象】
今天 XXX 反饋在接口機 XXX 上做 hdfs dfs -mv(同時執行 150 個 mv)操作的時候出現了大量的類似 hs_err_pid10147.log(10147 代表 java 進程號)這樣的文件,這個文件是 java 的致命錯誤日志,進程會直接崩潰。
【問題排查】
查看日志
hs_err_pid10147.log 中關鍵日志如下,或者是內存不足或者是 java 不能創建新的線程(即在系統層面限制了進程或線程創建的數據量)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources. # Possible reasons:
# The system is out of physical RAM or swap space # In 32 bit mode, the process size limit was hit
# Possible solutions:
# Reduce memory load on the system
# Increase physical memory or swap space # Check if swap backing store is full
# Use 64 bit Java on a 64 bit OS
# Decrease Java heap size (-Xmx/-Xms)
# Decrease number of Java threads
# Decrease Java thread stack sizes (-Xss)
# Set larger code cache with -XX:ReservedCodeCacheSize= # This output file may be truncated or incomplete.
#
# Out of Memory Error (gcTaskThread.cpp:48), pid=14974, tid=0x00007fcbeaf75700
#
# JRE veRegionServerion: (8.0_161-b12) (build )
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode linux-amd64 compressed oops)
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
確實是 hdfs mv 的 java 進程崩潰
VM Arguments:
jvm_args: -Dproc_dfs -Xmx1000m
-Dhadoop.log.dir=/opt/cloudera/parcels/CDH-5.13.1-1.cdh5.13.1.p0.2/ lib/hadoop/logs -Dhadoop.log.file=hadoop.log
-Dhadoop.home.dir=/opt/cloudera/parcels/CDH-5.13.1-1.cdh5.13.1.p0.2/lib/hadoop -Dhadoop.id.str= -Dhadoop.root.logger=INFO,console
-Djava.library.path=/opt/cloudera/parcels/CDH-5.13.1-1.cdh5.13.1.p0.2/lib/hadoop/lib/native -Dhadoop.policy.file=hadoop-policy.xml
-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Stack=true
-Dhadoop.security.logger=INFO,NullAppender java_command: org.apache.hadoop.fs.FsShell
-mv hdfs://10.244.12.214:8020/serv/smartsteps/raw/events/locationev ent/2019/05/15/011/000150_0.gz hdfs://10.244.12.214:8020/serv/smartsteps/raw/events/locationevent/2019/05/15/011/./CD051201010101ASMARTSTEPS1805151000170000151.011.gz
當時的內存還很大:
------------ S Y S T E M ---------------
OS:CentOS Linux release 7.2.1511 (Core)
uname:Linux 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC
2015 x86_64
libc:glibc 2.17 NPTL 2.17
rlimit: STACK 8192k, CORE 0k, NPROC 4096, NOFILE 65535, AS
infinity
load average:46.84 11.88 4.02
/proc/meminfo:
MemTotal: 131464872 kB
MemFree: 107818664 kB
MemAvailable: 125719212 kB
BuffeRegionServer: 2220 kB
Cached: 17496468 kB
SwapCached: 0 kB
Active: 10411796 kB
查看某個 java 進程堆棧信息,因為內存足夠故推斷是第二種可能(黃色)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources. # Possible reasons:
# The system is out of physical RAM or swap space # In 32 bit mode, the process size limit was hit
【解決方案】
用戶可以啟動的最大進程或線程數之前配置的是 1024,修改為 65535,在重新執行 150 個 mv 操作時正常
4.9、大數據作業JVM 內存崩潰 2
【現象】
今天 XXX 反饋在接口機 XXX 上做 hdfs dfs -mv(同時執行 150 個 mv)操作的時候出現了大量的類似 hs_err_pid3780.log(3780 代表 java 進程號)這樣的文件,這個文件是 java 的致命錯誤日志,進程會直接崩潰。
【排查問題】
查看日志
jvm 某個錯誤日志在 14:02 生成,需要使用 352321536 byte = 344064k 的內存
但是那時系統只剩下 342824k 內存,小於 344064k 的內存,故 jvm 崩潰,總結為:內存不足
【解決方案】
服務器擴內存或降低任務並發
4.10、集群作業數據傾斜任務排查
【現象】
作業監控發現作業存在數據傾斜
【問題排查】
在 YARN 監控頁面查看作業信息查看 yarn 監控頁面,此 job 共有 1009 個 reduce, 絕大部分 reduce 都是空跑沒有處理數據
下面看一個執行時間很長的 reduce, 大概 18 個多小時
此 reduce 處理的數據量為:86.99 億條
下面看一個執行時間短的 reduce, 大部分都在 3 分鍾以內
處理的數據量為 0