HDFS Read調優
在基於 HDFS 存儲的 HBase 中,主要有兩種調優方式:
- 繞過RPC的選項,稱為short circuit reads
- 開啟讓HDFS推測性地從多個datanode讀數據的選項,稱為 hedged reads
Short-Circuit Reads
一般來說,HBase RegionServer 與 HDFS DataNode在一起,所以可以實現很好的數據本地化。但是在早期Hadoop 1.0.0版本中,RegionServer 在與 DataNode通過RPC通信時,與其他常規客戶端一樣,需要經過整個RPC通信過程。在 Hadoop 1.0.0 版本之后,加入了short-circuit read選項,它可以完全繞過RPC棧,通過本地clients直接從底層文件系統讀數據。
Hadoop 2.x 之后進一步優化了這個實現。當前DataNode與HDFS客戶端(HBase也是其中一個)可以使用一個稱為file descriptor passing的功能,使得數據交換全部發生在OS kernel層。相較於之前的實現會更快,更高效。使得多個進程在同一個實例上進行高效地交互。
在Hadoop中,可以參考以下官方文檔配置啟用short-circuit reads:
https://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-hdfs/ShortCircuitLocalReads.html
下面是一個配置參考,需要在hbase-site.xml 與 hdfs-site.xml 兩個配置文件中均配置,且配置完后需重啟進程:
<property> <name>dfs.client.read.shortcircuit</name> <value>true</value> <description> This configuration parameter turns on short-circuit local reads. </description> </property> <property> <name>dfs.domain.socket.path</name> <value>/var/lib/hadoop-hdfs/dn_socket</value> <description> Optional. This is a path to a UNIX domain socket that will be used for communication between the DataNode and local HDFS clients. If the string "_PORT" is present in this path, it will be replaced by the TCP port of the DataNode. </description> </property>
需要注意的是:dfs.domain.socket.path指定的文件(可以先不存在)的owner必須為OS的root用戶,或者是運行datanode服務的用戶。
最后,short-circuit read buffers的默認大小由dfs.client.read.shortcircuit.buffer.size指定,對於很繁忙的HBase 集群來說,默認值可能會比較高。在HBase中,如果沒有沒有顯示指定此值,則會從默認的 1MB 直接降為 128KB(使用的是hbase.dfs.client.read.shortcircuit.buffer.size 屬性,默認為128KB)。
在HBase 中的HDFS客戶端,會為每個打開的data block分配一個direct byte buffer ,大小為參數hbase.dfs.client.read.shortcircuit.buffer.size 指定大小。此功能可以讓HBase永久保持它的HDFS文件打開,所以會很快地增加。
Hedged Reads
Hedged reads是HDFS的一個功能,在Hadoop 2.4.0之后引入。一般來說,每個讀請求都會由生成的一個線程處理。在Hedged reads 啟用后,客戶但可以等待一個預配置的時間,如果read沒有返回,則客戶端會生成第二個讀請求,訪問同一份數據的另一個block replica。之后,其中任意一個read 先返回的話,則另一個read請求則被丟棄。
Hedged reads使用的場景是:解決少概率的slow read(可能由瞬時錯誤導致,例如磁盤錯誤或是網絡抖動等)。
HBase region server 是一個 HDFS client,所以我們可以在HBase中啟用hedged reads,通過在 RegionServer 中的 hbase-site.xml 配置增加以下參數,並且根據實際環境對參數進行調整:
- def.client.hedged.read.threadpool.size:默認值為0。指定有多少線程用於服務hedged reads。如果此值設置為0(默認),則hedged reads為disabled狀態
- dfs.client.hedged.read.threshold.millis:默認為500(0.5秒):在spawning 第二個線程前,等待的時間。
下面是一個示例配置,設置等待閾值為10ms,並且線程數為20:
<property> <name>dfs.client.hedged.read.threadpool.size</name> <value>20</value> </property> <property> <name>dfs.client.hedged.read.threshold.millis</name> <value>10</value> </property>
需要注意的是:hedged reads 在HDFS中的功能,類似於MapReduce中的speculative execution:需要消耗額外的資源。例如,根據集群的負載與設定,它可能需要觸發很多額外的讀操作,且大部分是發送到遠端的block replicas。產生的額外的I/O、以及網絡可能會對集群性能造成較大影響。對此,需要在生產環境中的負載進行測試,以決定是否使用此功能。