天天看點

Hadoop-2.6.0 DFSClient Hedged Read實作分析一、簡介二、開啟

      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...