開始兼運維。對網上查詢到的運維問題進行簡單彙總.......................................................
一:namenode出現missing blocks
日常巡檢CDH集羣和HDP集羣發現有些namenode下有很多missing blocks ,hadoop數據存儲單位爲塊。一塊64M,這些Missing大多因爲元數據丟失而毀壞,很難恢復。就行硬盤故障一樣,需要fsck並且delete。
CDH集羣 :Cloudera manager的dashboard----HDFS----NameNode Web UI 如圖:
-----
HDP集羣:Ambari Server 的dashboard---HDFS Links---NameNode UI 如圖
清理Missing blocks步驟:登錄到console中控機,su hdfs 切換至hadoop集羣管理用戶
hdfs fsck /blocks-path/ 查看文件系統cluster,如:
hdfs fsck -fs hdfs://dc(n) /block-path/ 指定集羣
hdfs fsck -fs hdfs://dc /block-path/ -delete 如果上步元數據已損壞,則直接清理。
例: hdfs fsck /app-logs/mapred/mbbi/logs/application_1525315338835_219860/10.11.12.161
hdfs fsck -fs hdfs://dc1 /app-logs/mapred/mbbi/logs/application_1525315338835_219860/10.11.12.161
hdfs fsck -fs hdfs://dc1 /app-logs/mapred/mbbi/logs/application_1525315338835_219860/10.11.12.161 -delete
二: Spark on Yarn 查看任務日誌及狀態
1、根據application ID查看某個job的日誌
yarn logs -applicationId application_1525315338835_7483
2、查看某個job的狀態
yarn application -status application_1525315338835_7483
3、kill掉某個job(完全停止該job的執行,如果直接在Web上kill實際還會繼續運行)
yarn application -kill application_1525315338835_7483
也可以通過 http://ip:8088/cluster/scheduler/ 查看,在此Web界面可通過applicationId查看任務狀態和日誌。
三:Hadoop集羣用戶磁盤配額管理
1.hdfs是hadoop集羣的管理用戶,所以首先應該登陸集羣console並且su切換到hdfs用戶
2.磁盤配額分爲磁盤目錄文件數配額和磁盤空間配額。以msns用戶、1000000文件數、100T的配額空間爲例:
磁盤目錄文件數配額:hdfs dfsadmin -setQuota 1000000 /user/msns
磁盤空間配額:hdfs dfsadmin -setSpaceQuota 100t /user/msns
3.查看磁盤已有配額信息:
hadoop fs -count -q /user/msns
文件數限額 可用文件數 空間配額 可用空間 目錄數 文件數 總大小 文件/目錄名
4清空目錄配額信息:
清空文件數配額:hdfs dfsadmin -clrQuota /user/msns
清空磁盤空間配額:hdfs dfsadmin -clrSpaceQuota /user/msns
***5.注意這裏的空間配額是把副本容量也算入的,也就是所我們這裏的配額控制的是file_size x replications。即,如果我們要爲msns用戶設置100T的實際可用空間,副本因子爲3(一般爲3),那麼就需要用上面的命令配置300T的空間配額。文件數配額也類似。
四. hadoop集羣平滑退役/上線節點(DataName/tasktracker or NodeManager)
在生產環境中可能會遇到退役(下線)服務器需求,對於計算節點來說強制下線節點影響的只是task作業,但是對於HDFS來說,就會出現數據丟失的風險。當然hadoop也提供了平滑下線的機制。
4.1 退役DataNode
4.1.1 在namenode節點hdfs-site.xml中增加配置,PATH路徑根據自己實際情況進行修改
<property>
<name>dfs.hosts.exclude</name>
<value>/usr/local/service/hadoop/etc/hadoop/hdfsexcludedhosts</value>
</property>
4.1.2 在相關文件中添加需要退役的主機
[hadoop@10 ~]$ cat /usr/local/service/hadoop/etc/hadoop/hdfsexcludedhosts
10.0.0.1
10.0.0.2
4.1.3 在NameNode 運行以下命令,將經過審覈的DataNode更新至NameNode
[hadoop@10 ~]$ hdfs dfsadmin -refreshNodes
4.1.4 查看下線情況
hdfs dfsadmin -report
Decomissioning標記的即爲正在下線的DataNode,hadoop集羣會將下線的DataNode數據塊複製到其他節點。 複製完成之後會變成Decommission Status : Decommissioned。 2.1.5 下線完成後,清空/usr/local/service/hadoop/etc/hadoop/hdfsexcludedhosts 文件
[hadoop@10 ~]$ > /usr/local/service/hadoop/etc/hadoop/hdfsexcludedhosts
注意: 如果hadoop集羣爲HA,則需要在2個主控節點做相同操作
4.2 退役NodeManager 節點
4.2.1 在RM(ResourceManager)節點yarn-site.xml中增加配置,PATH路徑根據自己實際情況進行修改
<property>
<name>yarn.resourcemanager.nodes.exclude-path</name>
<value>/usr/local/service/hadoop/etc/hadoop/yarnexcludedhosts</value>
</property>
4.2.2 在相關文件中添加需要退役的主機
[hadoop@10 ~]$ cat /usr/local/service/hadoop/etc/hadoop/yarnexcludedhosts
10.0.0.1
10.0.0.2
4.2.3 在RM節點 運行以下命令,將經過審覈的NodeManager更新至RM
[hadoop@10 ~]$ yarn rmadmin -refreshNodes
4.2.4 下線完成後,在nodes include文件中去掉下線的機器,並清空exclude 文件
#yarn-site.xml 中nodes include 配置路徑,路徑根據自己實際情況
<property>
<name>yarn.resourcemanager.nodes.include-path</name>
<value>/usr/local/service/hadoop/etc/hadoop/yarnhosts</value>
</property>
[hadoop@10 hadoop]$ > /usr/local/service/hadoop/etc/hadoop/yarnexcludedhosts
注意: 如果hadoop集羣爲HA,則需要在2個主控節點做相同操作
4.3 上線DataNode節點
4.3.1 修改dfs.hosts對應配置文件,添加需要上線的機器
[hadoop@10 ~]$ cat /usr/local/service/hadoop/etc/hadoop/hdfshosts
10.0.100.53
10.0.100.52
4.3.2 在NameNode節點運行以下命令,將經過審覈的datanode更新至namenode
[hadoop@10 ~]$ hdfs dfsadmin -refreshNodes
4.3.3 檢查是否上線成功
hdfs dfsadmin -report
注意: 如果hadoop集羣爲HA,則需要在2個主控節點做相同操作
4.4 上線NodeManager節點
4.4.1 在nodes include文件中添加需要上線的機器
#yarn-site.xml 中nodes include 配置路徑,路徑根據自己實際情況
<property>
<name>yarn.resourcemanager.nodes.include-path</name>
<value>/usr/local/service/hadoop/etc/hadoop/yarnhosts</value>
</property>
[hadoop@10 ~]$ cat /usr/local/service/hadoop/etc/hadoop/yarnhosts
10.0.100.53
10.0.100.52
4.4.2 在RM節點 運行以下命令,將經過審覈的NodeManager更新至RM
[hadoop@10 ~]$ yarn rmadmin -refreshNodes
注意: 如果hadoop集羣爲HA,則需要在2個主控節點做相同操作
五. hadoop集羣標籤加入與退出
在生產環境中除了會遇到退役(下線)服務器需求,也可能會對集羣標籤做一些相關操作,下面主要說一下在集羣中如何從標籤中添加或退出節點
標籤相關操作
列出當前集羣中存在的節點標籤
yarn cluster --list-node-labels
刪除當前集羣中已存在的節點標籤
yarn rmadmin -removeFromClusterNodeLabels "<label1>,<label2>,..."
添加節點標籤到節點上
yarn rmadmin -replaceLabelsOnNode "node1.example.com=X"
通過如下命令可以批量從節點標籤中添加節點
$ cat addNodeList.txt
node1.example.com
node2.example.com
node3.example.com
node4.example.com
node5.example.com
$ cat addNodeList.txt | xargs -t -i yarn rmadmin -replaceLabelsOnNode "{}=X"
從節點標籤中移除節點
yarn rmadmin -replaceLabelsOnNode "node1.example.com"
通過如下命令可以批量從節點標籤中移除節點
cat addNodeList.txt
node1.example.com
node2.example.com
node3.example.com
node4.example.com
node5.example.com
$ cat addNodeList.txt | xargs -t -i yarn rmadmin -replaceLabelsOnNode "{}"
六、運維的不同場景
場景1:namenode節點故障,active namenode節點狀態切換?如何恢復?
1.1 Hadoop HA 的namenode狀態切換
- 模擬線上環境測試,namenode進程down掉一個後,active和standby狀態名稱節點切換正常。
namenode狀態切換命令:
hdfs haadmin -transitionToActive -forcemanual nn1 操作說明:當active節點正常時,使用hdfs haadmin -transitionToActive命令對兩個namenode節點切換都不起作用.
hdfs haadmin -transitionToStandby -forcemanual nn1 操作說明:當active節點正常時,執行可以將active的namenode節點轉換成standby狀態。
hdfs haadmin -failover --forcefence --forceactive nn1 nn2 操作說明:該命令在配置故障自動切換(dfs.ha.automatic-failover.enabled=true)之後,無法手動進行。可將該參數更改爲false(不需要重啓進程)後,重新執行該命令即可。hdfs haadmin -failover --forcefence --forceactive nn1 nn2
1.2 namenode故障如何恢復
-
如果是存放namenode元數據的硬盤損壞:
聯繫sa更換新的磁盤,從另一臺namenode機器上將${hadoop.tmp.dir}/dfs/name文件壓縮成tar包,scp到新磁盤上並解壓,該文件夾內存放的是集羣操作日誌EditLog和集羣block元數據Fsimage,然後啓動namenode進程完成故障恢復。namenode啓動後的數據同步: 新的namenode進程啓動後,會通過zk進行active、standby狀態選舉,正常的那臺namenode節點事務id最新所以會被繼續選爲active。另一臺新加入namenode爲standby狀態,並從JournalNode中同步最新的fsimage和editlog數據到自己的內存和磁盤文件中,最終使active nameonde和standby namenode元數據保持一致。
-
普通故障故障或cpu等其他硬件故障問題導致namenode進程故障:
聯繫sa更換損壞硬件,然後重啓namenode節點上的進程namenode、zkfc、nodemanager、datanode。 -
如果是服務器嚴重故障,需更換機器:
新機器儘量保留原域名,進行namenode遷移。(namenode遷移請參見下方場景2 )
場景2:namenode節點切換,namenode遷移?
namenode遷移流程:
- 申請新服務器,新服務器仍使用原服務器主機名。
- 基礎環境搭建。參考active的namenode環境,安裝jdk、配置環境變量。
根據新機器的硬件配置及原始配置,參考集羣其他機器環境配置,設置新機器的最大進程數、打開文件句柄數等。(hadoop集羣普通節點配置: 96G內存、12*6T硬盤、24核CPU)
[[email protected] ~]$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 。
file size (blocks, -f) unlimited
pending signals (-i) 385261
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 655350
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 65535
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
- 將存活的namenode節點上hadoop軟件打成壓縮包,傳到新的服務器。
tar -zcf hadoop-2.6.4.tar.gz ./hadoop-2.6.4
scp hadoop-2.6.4.tar.gz vm-dc002.ali.momo.com:/home/dc/datacenter/soft/hadoop/
tar -zxf hadoop-2.6.4.tar.gz -C ./
ln -s hadoop-2.6.4 default
- 找到core-site.xml配置文件中的hadoop.tmp.dir目錄,將存活namenode服務器上的${hadoop.tmp.dir}/dfs/name文件壓縮成tar包,傳送到新的namenode服務器並解壓,該文件與另一臺namenode的目錄結構保持一致。其他hdfs、yarn、mapreduce相關目錄會在相關進程啓動後自行建立。
tar -zcf ${hadoop.tmp.dir}/dfs/name.tar.gz ${hadoop.tmp.dir}/dfs/name
mkdir -p ${hadoop.tmp.dir}/dfs 在新機器上創建目錄
scp ${hadoop.tmp.dir}/dfs/name.tar.gz 新機器:${hadoop.tmp.dir}/dfs
tar -zxf ${hadoop.tmp.dir}/dfs/name.tar.gz -C ${hadoop.tmp.dir}/dfs/
- 修改新機器的主機名爲原namnode主機名,關機原機器或更換原機器主機名。
- 啓動namenode進程:hadoop-daemon.sh start namenode
- 啓動zkfc進程:hadoop-daemon.sh start zkfc 。
zkfc啓動後會觸發active namenode選舉,新namenode節點會被選爲standby。 - 檢查兩臺namenode的狀態和namenode進程日誌。
hdfs haadmin -getServiceState nn1 #檢查namenode節點狀態命令
hdfs haadmin -getServiceState nn2 #檢查namenode節點狀態命令
此時應留意兩臺機器namenode日誌和zkfc日誌,看是否正常,進程是否正常。如果nn1和nn2一個active一個standby,日誌正常無報錯,集羣block塊數量和數據正常查看均無異常,則namenode遷移完成。 - 如果上面運行有datanode和nodemanager,啓動相關進程:
hadoop-daemon.sh start datanode
yarn-daemon.sh start nodemanager
場景3:datanode故障問題。
3.1 磁盤故障導致datanode進程down
本次(2019-05-29日)採取措施:
- 修改hadoop集羣配置,增加datanode進程對磁盤的容錯能力,磁盤容錯數量設置爲3.(默認配置爲0)
- 增加磁盤健康狀態監控腳本(sa目前磁盤監控不完善容易漏報)。
總結: 這樣既能及時發現磁盤故障,也能將磁盤故障對hadoop集羣的影響降至最低。
日後正常維護:
磁盤故障報警後聯繫sa更換磁盤,更換完記得調整磁盤權限,然後重啓datanode進程。
3.2、datanode down後,hadoop集羣的容錯處理
模擬datanode進程down故障,觀察hadoop集羣的容錯處理:
- 首先hadoop集羣不會馬上認定datanode已經dead,會在10分鐘30秒後如果仍然沒有datanode心跳,纔會認爲該datannode進程死亡。
- 集羣在10分30秒後確認datanode進程dead之後,會將該dead節點上的block切換爲missing狀態,集羣的容錯機制將開始把missing的block在其他datanode上重新生成。
總結: datanode重啓操作儘量在10分鐘內完成,這樣對hadoop集羣的影響會最小,實際單臺datanode節點從啓動到在namenode上註冊成功並開始提供服務這個過程一般都在一分鐘內。
datanode啓動流程簡介:
- 加載並格式化hdfs的存儲目錄。
- 啓動DirectoryScanner等線程,掃描各存儲目錄下Block元數據。
- 向namonode註冊。
此時標誌着datanode啓動成功。
- 之後datanode開始向namenode上報block元數據信息,namenode校驗後如果跟自身內存中該datanode所屬的block元數據有出入則發佈容錯指令,datanode根據namenode指令執行容錯操作(新建、刪除block等)。
Block信息彙報
datanode隔6小時會向namenode彙報一次節點block信息。線上集羣未配置採用默認值。
官網配置 | 默認值 | 說明 |
---|---|---|
dfs.datanode.directoryscan.interval | 21600 | Interval in seconds for Datanode to scan data directories and reconcile the difference between blocks in memory and on the disk. |
dfs.blockreport.intervalMsec | 21600000 | Determines block reporting interval in milliseconds. |
參數備註:
directoryscan.interval 是掃描節點上的block信息,更新到內存中。6小時掃描一次
blockreport.intervalMsec 將內存中的block元數據上報namenode,這時候如果上報的block元數據跟namenode存儲的該節點元數據不符,則namenode會下發容錯指令(刪除,新建block等)給datanode執行。
注:這兩個線程都是各自以6小時爲週期,兩個線程間沒有固定時間間隔,各自工作。
DataNode健康狀態檢測:
hadoop datanode 節點超時時間設置:https://www.jianshu.com/p/1680bab38f06
測試機測試:datanode停掉10分鐘30秒後,集羣把datanode狀態切換爲dead。
超時時長的計算公式爲:timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval。
場景4:nodemanager節點故障,對sparkstreaming影響。
注:這部分請參考spark on yarn故障運維https://blog.csdn.net/qq_35488412/article/details/91041983
1.1 磁盤故障對yarn nodemanager的影響。
- 目前nodemanager默認容錯因子是0.25,不超過五分之一的磁盤故障不會影響nm進程啓動新的正常container。正在運行的container如果用到故障磁盤,則container上的任務會報錯拋出異常。
1.2 磁盤故障對spark任務的影響:
- spark ApplicationMaster進程可能會受到磁盤故障影響而出現進程異常,此時resourcemanager會自動重啓一個新的applicationmaster進程來繼續提供服務。所以spark的am服務不受影響。本次磁盤故障,spark一個實時任務的am進程在該服務器上,未受到影響,目前服務正常。
- 如果是spark任務的executor所在服務器磁盤故障,該executor進程會報錯,但其他正常節點executor能正常執行,spark任務整體不受影響。
1.3 NodeManager進程故障對Spark任務的影響
- 在測試服務器模擬NodeManager進程down,該機器的excutor掛掉,十分鐘後啓動新的executor進程。
場景4部分:具體細節請參見:spark on yarn故障運維:https://blog.csdn.net/qq_35488412/article/details/91041983
相關資料參考:
NameNode內存模型:https://blog.csdn.net/baiye_xing/article/details/76273495
源碼之HDFS之DataNode:啓動過程:https://www.jianshu.com/p/1b7fea129368
七、運維問題
1. 問題1
在集羣執行hive腳本時,hive.log報錯如下
java.lang.InterruptedException
解決辦法:
原因是因爲線程在等待過程中長期獲取不到資源被終止, 可以通過修改下面的配置進行優化:
dfs.datanode.handler.count(加大)DN的服務線程數。這些線程僅用於接收請求,處理業務命令
dfs.namenode.handler.count(加大) NN的服務線程數。用於處理RPC請求
2. 問題2
hive.log拋出異常信息如下
Error: java.lang.RuntimeException: org.apache.hive.com.esotericsoftware.kryo.KryoException: Encountered unregistered class ID: 73
Serialization trace:
colExprMap (org.apache.hadoop.hive.ql.exec.TableScanOperator)
aliasToWork (org.apache.hadoop.hive.ql.plan.MapWork)
解決辦法:
原因是hive-exec包的org.apache.hadoop.hive.ql.exec.Utilities中默認使用cloningQueryPlanKryo來存儲數據,多線程時覆蓋影響的0.13.1的bug,在0.14中已經得到修復,偶發性的數據序列化錯誤,很難重現, 可以修改hive.plan.serialization.format參數值爲javaXML來避免錯誤,默認是kryo序列化格式,沒進行嘗試因爲問題不容易重新;以下是參考資料
https://issues.apache.org/jira/browse/HIVE-8688?jql=project in (MAPREDUCE, HIVE, HADOOP, HDFS) AND text ~ "org.apache.hive.com.esotericsoftware.kryo.KryoException" ORDER BY priority DESC
https://issues.apache.org/jira/browse/HIVE-7711?jql=project in (MAPREDUCE, HIVE, HADOOP, HDFS) AND text ~ "org.apache.hive.com.esotericsoftware.kryo.KryoException" ORDER BY priority DESC
3. 問題3
java.io.IOException: 斷開的管道
下面是在執行hive ql時後臺報的錯誤,原因是在datanode上寫入文件時,傳輸管道中斷導致失敗
可以通過修改下面幾個參數對集羣讀寫性能進行優化
dfs.datanode.handler.count(加大)DN的服務線程數。這些線程僅用於接收請求,處理業務命令
dfs.namenode.handler.count(加大) NN的服務線程數。用於處理RPC請求
dfs.namenode.avoid.read.stale.datanode(true)決定是否避開從髒DN上讀數據。髒DN指在一個指定的時間間隔內沒有收到心跳信息。髒DN將被移到可以讀取(寫入)節點列表的尾端。嘗試開啓
dfs.namenode.avoid.write.stale.datanode(true) 和上面相似,是爲了避免向髒DN寫數據
4. 問題4
java.io.EOFException: Premature EOF
文件操作超租期,實際上就是data stream操作過程中文件被刪掉了 可以加大這個參數來進行優化dfs.datanode.max.transfer.threads;
參考資料:
https://issues.apache.org/jira/browse/HDFS-4723 http://www.sharpcloud.cn/thread-4927-1-1.html
5. 問題5
Connection reset by peer
java.io.IOException: Connection reset by peer
datanode重置鏈接 The client is stuck in an RPC to NameNode. Currently RPCs can be wait for a long time if the server is busy.
可以通過修改下面幾個參數來優化
dfs.namenode.handler.count(加大) NN的服務線程數。用於處理RPC請求
dfs.namenode.replication.interval(減小) NN週期性計算DN的副本情況的頻率,秒
dfs.client.failover.connection.retries(建議加大) 專家設置。IPC客戶端失敗重試次數。在網絡不穩定時建議加大此值
dfs.client.failover.connection.retries.on.timeouts(網絡不穩定建議加大)專家設置。IPC客戶端失敗重試次數,此失敗僅指超時失敗。在網絡不穩定時建議加大此值
參考資料:https://issues.apache.org/jira/browse/HADOOP-3657
6. 問題6
SemanticException Schema of both sides of union should match
2015-08-10 17:22:35,390 ERROR [main]: ql.Driver (SessionState.java:printError(567)) - FAILED: SemanticException Schema of both sides of union should match.
語法錯誤,使用union查詢時查詢兩個表的內容不同,測試sql時報的錯,不是集羣作業的,檢查hive ql改正即可
7. 問題7
java.net.SocketTimeoutException
IO超時加大下面倆個參數即可
dfs.datanode.socket.write.timeout (加大)向datanode寫入數據超時設置
dfs.client.socket-timeout (加大) dfsclients與集羣間進行網絡通信的超時設置