大資料開發基礎之HDFS引數調優步驟分享
1.NameNode資料目錄
dfs.name.dir, dfs.namenode.name.dir
指定一個本地檔案系統路徑,決定NN在何處存放fsimage和editlog檔案。可以通過逗號分隔指定多個路徑. 目前我們的產線環境只配大資料培訓置了一個目錄,並存放在了做了RAID1或RAID5的磁碟上。
2.DataNode資料目錄
dfs.data.dir, dfs.datanode.data.dir
指定DN存放塊資料的本地盤路徑,可以通過逗號分隔指定多個路徑。在生產環境可能會在一個DN上掛多塊盤。
3.資料塊的副本數
dfs.replication
資料塊的副本數,預設值為3
4.資料塊大小
dfs.block.size
HDFS資料塊的大小,預設為128M,目前我們產線環境配置的是1G
5.HDFS做均衡時使用的最大頻寬
dfs.datanode.balance.bandwidthPerSec
HDFS做均衡時使用的最大頻寬,預設為1048576,即1MB/s,對大多數千兆甚至萬兆頻寬的叢集來說過小。不過該值可以在啟動balancer指令碼時再設定,可以不修改叢集層面預設值。目前目前我們產線環境設定的是50M/s~100M/s
6.磁碟可損壞數
dfs.datanode.failed.volumes.tolerated
DN多少塊盤損壞後停止服務,預設為0,即一旦任何磁碟故障DN即關閉。對盤較多的叢集(例如每DN12塊盤),磁碟故障是常態,通常可以將該值設定為1或2,避免頻繁有DN下線。
7.資料傳輸連線數
dfs.datanode.max.xcievers
DataNode可以同時處理的資料傳輸連線數,即指定在DataNode內外傳輸資料使用的最大執行緒數。官方將該引數的命名改為dfs.datanode.max.transfer.threads,預設值為4096,推薦值為8192,我們產線環境也是8192
8.NameNode處理RPC呼叫的執行緒數
dfs.namenode.handler.count
NameNode中用於處理RPC呼叫的執行緒數,預設為10。對於較大的叢集和配置較好的伺服器,可適當增加這個數值來提升NameNode RPC服務的併發度,該引數的建議值:叢集的自然對數 * 20
python -c 'import math ; print int(math.log(N) * 20)'
我們800+節點產線環境配置的是200~500之間
9.NameNode處理datanode 上報資料塊和心跳的執行緒數
dfs.namenode.service.handler.count
用於處理datanode 上報資料塊和心跳的執行緒數量,與dfs.namenode.handler.count演算法一致
10.DataNode處理RPC呼叫的執行緒數
dfs.datanode.handler.count
DataNode中用於處理RPC呼叫的執行緒數,預設為3。可適當增加這個數值來提升DataNode RPC服務的併發度,執行緒數的提高將增加DataNode的記憶體需求,因此,不宜過度調整這個數值。我們產線環境設定的是10
11.DataNode最大傳輸執行緒數
dfs.datanode.max.xcievers
最大傳輸執行緒數 指定在 DataNode 內外傳輸資料使用的最大執行緒數。
這個值是指定 datanode 可同時處理的最大檔案數量,推薦將這個值調大,預設是256,最大值可以配置為65535,我們產線環境配置的是8192。
12.讀寫資料時的快取大小
io.file.buffer.size
–設定在讀寫資料時的快取大小,應該為硬體分頁大小的2倍
我們產線環境設定的為65536 ( 64K)
13.冗餘資料塊刪除
在日常維護hadoop叢集的過程中發現這樣一種情況:
某個節點由於網路故障或者DataNode程序死亡,被NameNode判定為死亡,HDFS馬上自動開始資料塊的容錯拷貝;當該節點重新新增到叢集中時,由於該節點上的資料其實並沒有損壞,所以造成了HDFS上某些block的備份數超過了設定的備份數。通過觀察發現,這些多餘的資料塊經過很長的一段時間才會被完全刪除掉,那麼這個時間取決於什麼呢?
該時間的長短跟資料塊報告的間隔時間有關。Datanode會定期將當前該結點上所有的BLOCK資訊報告給NameNode,引數dfs.blockreport.intervalMsec就是控制這個報告間隔的引數。
hdfs-site.xml檔案中有一個引數:
<property>
<name>dfs.blockreport.intervalMsec</name>
<value>3600000</value>
<description>Determines block reporting interval in milliseconds.</description>
</property>
其中3600000為預設設定,3600000毫秒,即1個小時,也就是說,塊報告的時間間隔為1個小時,所以經過了很長時間這些多餘的塊才被刪除掉。通過實際測試發現,當把該引數調整的稍小一點的時候(60秒),多餘的資料塊確實很快就被刪除了
14.新增塊延遲彙報
當datanode上新寫完一個塊,預設會立即彙報給namenode。在一個大規模Hadoop叢集上,每時每刻都在寫資料,datanode上隨時都會有寫完資料塊然後彙報給namenode的情況。因此namenode會頻繁處理datanode這種快彙報請求,會頻繁地持有鎖,其實非常影響其他rpc的處理和響應時間。
通過延遲快彙報配置可以減少datanode寫完塊後的塊彙報次數,提高namenode處理rpc的響應時間和處理速度。
<property>
<name>dfs.blockreport.incremental.intervalMsec</name>
<value>300</value>
</property>
我們產線環境HDFS叢集上此引數配置為500毫秒,就是當datanode新寫一個塊,不是立即彙報給namenode,而是要等待500毫秒,在此時間段內新寫的塊一次性彙報給namenode。
15.增大同時開啟的檔案描述符和網路連線上限
使用ulimit命令將允許同時開啟的檔案描述符數目上限增大至一個合適的值。同時調整核心引數net.core.somaxconn網路連線數目至一個足夠大的值。
補充:net.core.somaxconn的作用
net.core.somaxconn是Linux中的一個kernel引數,表示socket監聽(listen)的backlog上限。什麼是backlog呢?backlog就是socket的監聽佇列,當一個請求(request)尚未被處理或建立時,它會進入backlog。而socket server可以一次性處理backlog中的所有請求,處理後的請求不再位於監聽佇列中。當server處理請求較慢,以至於監聽佇列被填滿後,新來的請求會被拒絕。在Hadoop 1.0中,引數ipc.server.listen.queue.size控制了服務端socket的監聽佇列長度,即backlog長度,預設值是128。而Linux的引數net.core.somaxconn預設值同樣為128。當服務端繁忙時,如NameNode或JobTracker,128是遠遠不夠的。這樣就需要增大backlog,例如我們的叢集就將ipc.server.listen.queue.size設成了32768,為了使得整個引數達到預期效果,同樣需要將kernel引數net.core.somaxconn設成一個大於等於32768的值。