datanode程序死亡或者網絡故障造成datanode無法與namenode通信,namenode不會立即把該節點判定為死亡,要經過一段時間,這段時間暫稱作逾時時長。hdfs預設的逾時時長為10分鐘+30秒。如果定義逾時時間為timeout,則逾時時長的計算公式為:
timeout = 2 * heartbeat.recheck.interval + 10 *dfs.heartbeat.interval。
而預設的heartbeat.recheck.interval大小為5分鐘,dfs.heartbeat.interval預設為3秒。
需要注意的是hdfs-site.xml配置檔案中的heartbeat.recheck.interval的機關為毫秒,dfs.heartbeat.interval的機關為秒。是以,舉個例子,如果heartbeat.recheck.interval設定為5000(毫秒),dfs.heartbeat.interval設定為3(秒,預設),則總的逾時時間為40秒。
hdfs-site.xml中的參數設定格式:
<property>
<name>heartbeat.recheck.interval</name>
<value>2000</value>
</property>
<name>dfs.heartbeat.interval</name>
<value>1</value>
hadoop的日志目錄(/home/toto/software/hadoop-2.8.0/logs)
1、hadoop啟動不正常
用浏覽器通路namenode的50070端口,不正常,需要診斷問題出在哪裡:
a、在伺服器的終端指令行使用jps檢視相關程序
(namenode1個節點 datanode3個節點 secondary namenode1個節點)
b、如果已經知道了啟動失敗的服務程序,進入到相關程序的日志目錄下,檢視日志,分析異常的原因
1)配置檔案出錯,saxparser exception; ——找到錯誤提示中所指出的配置檔案檢查修改即可
2)unknown host——主機名不認識,配置/etc/hosts檔案即可,或者是配置檔案中所用主機名跟實際不一緻
(注:在配置檔案中,統一使用主機名,而不要用ip位址)
3)directory 通路異常——檢查namenode的工作目錄,看權限是否正常
start-dfs.sh啟動後,發現有datanode啟動不正常
a)檢視datanode的日志,看是否有異常,如果沒有異常,手動将datanode啟動起來
sbin/hadoop-daemon.sh start datanode
b)很有可能是slaves檔案中就沒有列出需要啟動的datanode
c)排除上述兩種情況後,基本上,能在日志中看到異常資訊:
1、配置檔案
2、ssh免密登陸沒有配置好
3、datanode的身份辨別跟namenode的叢集身份辨別不一緻(删掉datanode的工作目錄)
在日常維護hadoop叢集的過程中發現這樣一種情況:
某個節點由于網絡故障或者datanode程序死亡,被namenode判定為死亡,hdfs馬上自動開始資料塊的容錯拷貝;當該節點重新添加到叢集中時,由于該節點上的資料其實并沒有損壞,是以造成了hdfs上某些block的備份數超過了設定的備份數。通過觀察發現,這些多餘的資料塊經過很長的一段時間才會被完全删除掉,那麼這個時間取決于什麼呢?
該時間的長短跟資料塊報告的間隔時間有關。datanode會定期将目前該結點上所有的block資訊報告給namenode,
參數dfs.blockreport.intervalmsec就是控制這個報告間隔的參數。
hdfs-site.xml檔案中有一個參數:
<name>dfs.blockreport.intervalmsec</name>
<value>3600000</value>
<description>determines block reporting interval in milliseconds.</description>
其中3600000為預設設定,3600000毫秒,即1個小時,也就是說,塊報告的時間間隔為1個小時,是以經過了很長
時間這些多餘的塊才被删除掉。通過實際測試發現,當把該參數調整的稍小一點的時候(60秒),多餘的資料塊
确實很快就被删除了。
當namenode發現叢集中的block丢失數量達到一個閥值時,namenode就進入安全模式狀态,不再接受用戶端的資料更新請求
在正常情況下,namenode也有可能進入安全模式:
叢集啟動時(namenode啟動時)必定會進入安全模式,然後過一段時間會自動退出安全模式(原因是datanode彙報的過程有一段持續時間)
也确實有異常情況下導緻的安全模式
原因:block确實有缺失
措施:可以手動讓namenode退出安全模式,bin/hdfsdfsadmin -safemode leave
或者:調整safemode門限值: dfs.safemode.threshold.pct=0.999f
第一種方式:同步到網絡時間伺服器
#ntpdate time.windows.com
将硬體時間設定為目前系統時間。
#hwclock –w
加入crontab:
30 8 * * * root /usr/sbin/ntpdate192.168.0.1; /sbin/hwclock -w 每天的8:30将進行一次時間同步。
重新開機crond服務:
service crond restart
第二種方式:同步到區域網路内部的一台時間同步伺服器
一、搭建時間同步伺服器
1、編譯安裝ntp server
rpm -qa | grep ntp
若沒有找到,則說明沒有安裝ntp包,從CD光牒上找到ntp包,使用
rpm -uvh ntp***.rpm
進行安裝
2、修改ntp.conf配置檔案
vi /etc/ntp.conf
①、第一種配置:允許任何ip的客戶機都可以進行時間同步
将“restrict default nomodify notrap noquery”這行修改成:
restrict default nomodify notrap
配置檔案示例:/etc/ntp.conf
②、第二種配置:隻允許192.168.211.***網段的客戶機進行時間同步
在restrict default nomodify notrap noquery(表示預設拒絕所有ip的時間同步)之後增加一行:
restrict 192.168.211.0 mask 255.255.255.0nomodify notrap
3、啟動ntp服務
service ntpd start
開機啟動服務
chkconfig ntpd on
4、ntpd啟動後,客戶機要等幾分鐘再與其進行時間同步,否則會提示“no server suitable for synchronization found”錯誤。
二、配置時間同步客戶機
手工執行 ntpdate <ntp server> 來同步
或者利用crontab來執行
crontab -e
0 21 * * * ntpdate 192.168.211.22 >>/root/ntpdate.log 2>&1
每天晚上9點進行同步
附:
當用ntpdate -d 來查詢時會發現導緻 no server suitable for synchronization found 的錯誤的資訊有以下2個:
錯誤1.server dropped: strata too high
在ntp用戶端運作ntpdate serverip,出現no server suitable for synchronization found的錯誤。
在ntp用戶端用ntpdate –d serverip檢視,發現有“server dropped: strata too high”的錯誤,并且顯示“stratum 16”。而正常情況下stratum這個值得範圍是“0~15”。
這是因為ntp server還沒有和其自身或者它的server同步上。
以下的定義是讓ntp server和其自身保持同步,如果在/ntp.conf中定義的server都不可用時,将使用local時間作為ntp服務提供給ntp用戶端。
server 127.127.1.0
fudge 127.127.1.0 stratum 8
在ntp server上重新啟動ntp服務後,ntp server自身或者與其server的同步的需要一個時間段,這個過程可能是5分鐘,在這個時間之内在用戶端運作ntpdate指令時會産生no server suitable for synchronization found的錯誤。
那麼如何知道何時ntp server完成了和自身同步的過程呢?
在ntp server上使用指令:
# watch ntpq -p
出現畫面:
every 2.0s: ntpq -p thu jul 10 02:28:32 2008
remote refid st t when poll reach delay offset jitter
==============================================================================
192.168.30.22 local(0) 8 u 22 64 1 2.113 179133. 0.001
local(0) local(0) 10 l 21 64 1 0.000 0.000 0.001
注意local的這個就是與自身同步的ntp server。
注意reach這個值,在啟動ntp server服務後,這個值就從0開始不斷增加,當增加到17的時候,從0到17是5次的變更,每一次是poll的值的秒數,是64秒*5=320秒的時間。
如果之後從ntp用戶端同步ntp server還失敗的話,用ntpdate –d來查詢詳細錯誤資訊,再做判斷。
錯誤2.server dropped: no data
從用戶端執行netdate –d時有錯誤資訊如下:
transmit(192.168.30.22)transmit(192.168.30.22)
transmit(192.168.30.22)
192.168.30.22: server dropped: no data
server 192.168.30.22, port 123
.....
28 jul 17:42:24 ntpdate[14148]: no serversuitable for synchronization found出現這個問題的原因可能有2:
1。檢查ntp的版本,如果你使用的是ntp4.2(包括4.2)之後的版本,在restrict的定義中使用了notrust的話,會導緻以上錯誤。
使用以下指令檢查ntp的版本:
# ntpq -c version
下面是來自ntp官方網站的說明:
the behavior of notrust changed betweenversions 4.1 and 4.2.
in 4.1 (and earlier) notrust meant"don't trust this host/subnet for time".
in 4.2 (and later) notrust means"ignore all ntp packets that are not cryptographicallyauthenticated." this forces remote time servers to authenticate themselvesto your (client) ntpd
解決:
把notrust去掉。
2。檢查ntp server的防火牆。可能是server的防火牆屏蔽了upd123端口。
可以用指令
#service iptables stop
來關掉iptables服務後再嘗試從ntp用戶端的同步,如果成功,證明是防火牆的問題,需要更改iptables的設定。
hadoop機架感覺
1.背景
hadoop在設計時考慮到資料的安全與高效,資料檔案預設在hdfs上存放三份,存儲政策為本地一份,同機架内其它某一節點上一份,不同機架的某一節點上一份。這樣如果本地資料損壞,節點可以從同一機架内的相鄰節點拿到資料,速度肯定比從跨機架節點上拿資料要快;同時,如果整個機架的網絡出現異常,也能保證在其它機架的節點上找到資料。為了降低整體的帶寬消耗和讀取延時,hdfs會盡量讓讀取程式讀取離它最近的副本。如果在讀取程式的同一個機架上有一個副本,那麼就讀取該副本。如果一個hdfs叢集跨越多個資料中心,那麼用戶端也将首先讀本地資料中心的副本。那麼hadoop是如何确定任意兩個節點是位于同一機架,還是跨機架的呢?答案就是機架感覺。
預設情況下,hadoop的機架感覺是沒有被啟用的。是以,在通常情況下,hadoop叢集的hdfs在選機器的時候,是随機選擇的,也就是說,很有可能在寫資料時,hadoop将第一塊資料block1寫到了rack1上,然後随機的選擇下将block2寫入到了rack2下,此時兩個rack之間産生了資料傳輸的流量,再接下來,在随機的情況下,又将block3重新又寫回了rack1,此時,兩個rack之間又産生了一次資料流量。在job處理的資料量非常的大,或者往hadoop推送的資料量非常大的時候,這種情況會造成rack之間的網絡流量成倍的上升,成為性能的瓶頸,進而影響作業的性能以至于整個叢集的服務
2.配置
預設情況下,namenode啟動時候日志是這樣的:
2013-09-22 17:27:26,423 infoorg.apache.hadoop.net.networktopology: adding a new node: /default-rack/ 192.168.147.92:50010
每個ip 對應的機架id都是 /default-rack ,說明hadoop的機架感覺沒有被啟用。
要将hadoop機架感覺的功能啟用,配置非常簡單,在 namenode所在節點的/home/bigdata/apps/hadoop/etc/hadoop的core-site.xml配置檔案中配置一個選項:
<name>topology.script.file.name</name>
<value>/home/bigdata/apps/hadoop/etc/hadoop/topology.sh</value>
這個配置選項的value指定為一個可執行程式,通常為一個腳本,該腳本接受一個參數,輸出一個值。接受的參數通常為某台datanode機器的ip位址,而輸出的值通常為該ip位址對應的datanode所在的rack,例如”/rack1”。namenode啟動時,會判斷該配置選項是否為空,如果非空,則表示已經啟用機架感覺的配置,此時namenode會根據配置尋找該腳本,并在接收到每一個datanode的heartbeat時,将該datanode的ip位址作為參數傳給該腳本運作,并将得到的輸出作為該datanode所屬的機架id,儲存到記憶體的一個map中.
至于腳本的編寫,就需要将真實的網絡拓樸和機架資訊了解清楚後,通過該腳本能夠将機器的ip位址和機器名正确的映射到相應的機架上去。一個簡單的實作如下:
#!/bin/bash
hadoop_conf=/home/bigdata/apps/hadoop/etc/hadoop
while [ $# -gt 0 ] ; do
nodearg=$1
exec<${hadoop_conf}/topology.data
result=""
whileread line ; do
ar=( $line )
if [ "${ar[0]}" = "$nodearg" ]||["${ar[1]}" = "$nodearg" ]; then
result="${ar[2]}"
fi
done
shift
if[ -z "$result" ] ; then
echo -n "/default-rack"
else
echo -n "$result"
fi
topology.data,格式為:節點(ip或主機名) /交換機xx/機架xx
192.168.147.91 tbe192168147091 /dc1/rack1
192.168.147.92 tbe192168147092 /dc1/rack1
192.168.147.93 tbe192168147093 /dc1/rack2
192.168.147.94 tbe192168147094 /dc1/rack3
192.168.147.95 tbe192168147095 /dc1/rack3
192.168.147.96 tbe192168147096 /dc1/rack3
需要注意的是,在namenode上,該檔案中的節點必須使用ip,使用主機名無效,而jobtracker上,該檔案中的節點必須使用主機名,使用ip無效,是以,最好ip和主機名都配上。
這樣配置後,namenode啟動時候日志是這樣的:
2013-09-23 17:16:27,272 infoorg.apache.hadoop.net.networktopology: adding a new node: /dc1/rack3/ 192.168.147.94:50010
說明hadoop的機架感覺已經被啟用了。
檢視hadoop機架資訊指令:
./hadoop dfsadmin -printtopology
rack: /dc1/rack1
192.168.147.91:50010 (tbe192168147091)
192.168.147.92:50010 (tbe192168147092)
rack: /dc1/rack2
192.168.147.93:50010 (tbe192168147093)
rack: /dc1/rack3
192.168.147.94:50010 (tbe192168147094)
192.168.147.95:50010 (tbe192168147095)
192.168.147.96:50010 (tbe192168147096)
3.增加資料節點,不重新開機namenode
假設hadoop叢集在192.168.147.68上部署了namenode和datanode,啟用了機架感覺,執行bin/hadoopdfsadmin -printtopology看到的結果:
192.168.147.68:50010 (dbj68)
現在想增加一個實體位置在rack2的資料節點192.168.147.69到叢集中,不重新開機namenode。
首先,修改namenode節點的topology.data的配置,加入:192.168.147.69 dbj69 /dc1/rack2,儲存。
192.168.147.68 dbj68 /dc1/rack1
192.168.147.69 dbj69 /dc1/rack2
然後,sbin/hadoop-daemons.sh start datanode啟動資料節點dbj69,任意節點執行bin/hadoopdfsadmin -printtopology 看到的結果:
192.168.147.69:50010 (dbj69)
說明hadoop已經感覺到了新加入的節點dbj69。
注意:如果不将dbj69的配置加入到topology.data中,執行sbin/hadoop-daemons.sh start datanode啟動資料節點dbj69,datanode日志中會有異常發生,導緻dbj69啟動不成功。
2013-11-21 10:51:33,502 fatalorg.apache.hadoop.hdfs.server.datanode.datanode: initialization failed forblock pool block pool bp-1732631201-192.168.147.68-1385000665316 (storage idds-878525145-192.168.147.69-50010-1385002292231) service todbj68/192.168.147.68:9000
org.apache.hadoop.ipc.remoteexception(org.apache.hadoop.net.networktopology$invalidtopologyexception):invalid network topology. you cannot have a rack and a non-rack node at thesame level of the network topology.
atorg.apache.hadoop.net.networktopology.add(networktopology.java:382)
atorg.apache.hadoop.hdfs.server.blockmanagement.datanodemanager.registerdatanode(datanodemanager.java:746)
atorg.apache.hadoop.hdfs.server.namenode.fsnamesystem.registerdatanode(fsnamesystem.java:3498)
atorg.apache.hadoop.hdfs.server.namenode.namenoderpcserver.registerdatanode(namenoderpcserver.java:876)
atorg.apache.hadoop.hdfs.protocolpb.datanodeprotocolserversidetranslatorpb.registerdatanode(datanodeprotocolserversidetranslatorpb.java:91)
atorg.apache.hadoop.hdfs.protocol.proto.datanodeprotocolprotos$datanodeprotocolservice$2.callblockingmethod(datanodeprotocolprotos.java:20018)
atorg.apache.hadoop.ipc.protobufrpcengine$server$protobufrpcinvoker.call(protobufrpcengine.java:453)
atorg.apache.hadoop.ipc.rpc$server.call(rpc.java:1002)
atorg.apache.hadoop.ipc.server$handler$1.run(server.java:1701)
atorg.apache.hadoop.ipc.server$handler$1.run(server.java:1697)
atjava.security.accesscontroller.doprivileged(native method)
atjavax.security.auth.subject.doas(subject.java:415)
atorg.apache.hadoop.security.usergroupinformation.doas(usergroupinformation.java:1408)
atorg.apache.hadoop.ipc.server$handler.run(server.java:1695)
atorg.apache.hadoop.ipc.client.call(client.java:1231)
atorg.apache.hadoop.ipc.protobufrpcengine$invoker.invoke(protobufrpcengine.java:202)
at$proxy10.registerdatanode(unknown source)
atsun.reflect.nativemethodaccessorimpl.invoke0(native method)
atsun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:57)
atsun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)
atjava.lang.reflect.method.invoke(method.java:601)
atorg.apache.hadoop.io.retry.retryinvocationhandler.invokemethod(retryinvocationhandler.java:164)
atorg.apache.hadoop.io.retry.retryinvocationhandler.invoke(retryinvocationhandler.java:83)
atorg.apache.hadoop.hdfs.protocolpb.datanodeprotocolclientsidetranslatorpb.registerdatanode(datanodeprotocolclientsidetranslatorpb.java:149)
atorg.apache.hadoop.hdfs.server.datanode.bpserviceactor.register(bpserviceactor.java:619)
atorg.apache.hadoop.hdfs.server.datanode.bpserviceactor.connecttonnandhandshake(bpserviceactor.java:221)
atorg.apache.hadoop.hdfs.server.datanode.bpserviceactor.run(bpserviceactor.java:660)
atjava.lang.thread.run(thread.java:722)
4.節點間距離計算
有了機架感覺,namenode就可以畫出下圖所示的datanode網絡拓撲圖。d1,r1都是交換機,最底層是datanode。則h1的rackid=/d1/r1/h1,h1的parent是r1,r1的是d1。這些rackid資訊可以通過topology.script.file.name配置。有了這些rackid資訊就可以計算出任意兩台datanode之間的距離,得到最優的存放政策,優化整個叢集的網絡帶寬均衡以及資料最優配置設定。
distance(/d1/r1/h1,/d1/r1/h1)=0 相同的datanode
distance(/d1/r1/h1,/d1/r1/h2)=2 同一rack下的不同datanode
distance(/d1/r1/h1,/d1/r2/h4)=4 同一idc下的不同datanode
distance(/d1/r1/h1,/d2/r3/h7)=6 不同idc下的datanode