DFSClient Hedged Read是Hadoop-2.4.0引入的一個新特性,如果讀取一個資料塊的操作比較慢,DFSClient Hedged Read将會開啟一個從另一個副本的hedged讀操作。我們會選取首先完成的操作,并取消其它操作。這個Hedged讀特性将有助于控制異常值,比如由于命中一個壞盤等原因而需要花費較長時間的異常閱讀等。
DFSClient Hedged Read特性預設是關閉的。如果要開啟,則需配置如下:
1、dfs.client.hedged.read.threadpool.size
并發Hedged 讀的線程池大小
2、dfs.client.hedged.read.threshold.millis
開啟一個Hedged 讀前的等待時間(毫秒)
三、實作分析
1、DFSClient實作
DFSClient中,定義了一個靜态線程池:
DFSClient的構造函數中,有如下處理:
根據參數dfs.client.hedged.read.threadpool.size确定是否執行個體化線程池,而initThreadsNumForHedgedReads()方法如下:
執行個體化了一個ThreadPoolExecutor,corePoolSize大小是1,maximumPoolSize大小是參數,workQueue為一個沒有資料緩沖的阻塞隊列,ThreadFactory是Hadoop自己實作的背景線程工廠,并自定義了RejectedExecutionHandler,主要是在有異常時實作HEDGED_READ_METRIC.incHedgedReadOpsInCurThread(),即計數器減1。
最後,DFSClient提供了如下幾個get和set方法,友善輸入流調用:
2、DFSInputStream實作
在輸入流DFSInputStream的read方法中,會通過dfsClient.isHedgedReadsEnabled()判斷是否開啟了Hedged Read特性,在其開啟的情況下,調用hedgedFetchBlockByteRange()方法進行資料讀取操作,如下:
hedgedFetchBlockByteRange()方法通過ExecutorCompletionService和Future List實作了Hedged Read特性,具體實作如下:
1、構造一個futures清單:
2、構造一個ExecutorCompletionService:
3、計算資料塊和長度;
4、在一個while循環内,分兩種情況:
1)第一次讀取時:從NameNode選取DataNode,即chooseDataNode,構造Callable并送出至hedgedService,擷取Future<ByteBuffer> firstRequest,然後
用非阻塞的poll擷取結果future,判斷future是否成功,成功即傳回,否則在ignored中添加下次需要忽略的本節點,incHedgedReadOps計數并繼續;
2)通過getBestNodeDNAddrPair或chooseDataNode選取DataNode,構造Callable并送出至hedgedService,通過getFirstToComplete擷取第一個成功的結果後,調用cancelAll取消其它的,并計數,否則也是計數外加忽略本次DataNode。
getFirstToComplete中,是通過阻塞式的hedgedService.take()來實作的。
具體代碼如下:
而getFirstToComplete實作如下:
over...