1. 程式人生 > >HDFS 副本存放磁碟選擇策略詳解

HDFS 副本存放磁碟選擇策略詳解


在 HDFS 中,DataNode 將資料塊儲存到本地檔案系統目錄中,具體的目錄可以通過配置 hdfs-site.xml 裡面的 dfs.datanode.data.dir 引數。在典型的安裝配置中,一般都會配置多個目錄,並且把這些目錄分別配置到不同的裝置上,比如分別配置到不同的HDD(HDD的全稱是Hard Disk Drive)和SSD(全稱Solid State Drives,就是我們熟悉的固態硬碟)上。

當我們往 HDFS 上寫入新的資料塊,DataNode 將會使用 volume 選擇策略來為這個塊選擇儲存的地方。通過引數 dfs.datanode.fsdataset.volume.choosing.policy 來設定,這個引數目前支援兩種磁碟選擇策略

  • round-robin

  • available space

dfs.datanode.fsdataset.volume.choosing.policy引數的預設值是 org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy。這兩種磁碟選擇策略都是對 org.apache.hadoop.hdfs.server.datanode.fsdataset.VolumeChoosingPolicy 介面進行實現,VolumeChoosingPolicy 介面其實就定義了一個函式:chooseVolume 如下:

chooseVolume 函式對指定的副本從 volumes 裡面選定滿足條件的磁碟。下面對 Hadoop 內建的兩種磁碟選擇策略進行詳細的介紹。 

round-robin 磁碟選擇策略 

從名字就可以看出,這種磁碟選擇策略是基於輪詢的方式,具體的實現類是 org.apache.hadoop.hdfs.server.datanode.fsdataset.RoundRobinVolumeChoosingPolicy。它的實現很簡單:

volumes 引數其實就是通過 dfs.datanode.data.dir 配置的目錄。blockSize 就是咱們副本的大小。RoundRobinVolumeChoosingPolicy 策略先輪詢的方式拿到下一個 volume ,如果這個 volume 的可用空間比需要存放的副本大小要大,則直接返回這個 volume 用於存放資料;如果當前 volume 的可用空間不足以存放副本,則以輪詢的方式選擇下一個 volume,直到找到可用的 volume,如果遍歷完所有的 volumes 還是沒有找到可以存放下副本的 volume,則丟擲 DiskOutOfSpaceException 異常。 

從上面的策略可以看出,這種輪詢的方式雖然能夠保證所有磁碟都能夠被使用,但是如果 HDFS 上的檔案存在大量的刪除操作,可能會導致磁碟資料的分佈不均勻,比如有的磁碟儲存得很滿了,而有的磁碟可能還有很多儲存空間沒有得到利用。 

available space 磁碟選擇策略

可用空間磁碟選擇策略是從 Hadoop 2.1.0 開始引入的(詳情參見:HDFS-1804)。這種策略優先將資料寫入具有最大可用空間的磁碟(通過百分比計算的)。在實現上可用空間選擇策略內部用到了上面介紹的輪詢磁碟選擇策略,具體的實現程式碼在 org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy 類中,核心實現如下:

areAllVolumesWithinFreeSpaceThreshold 函式的作用是先計算所有 volumes 的最大可用空間和最小可用空間,然後使用最大可用空間減去最小可用空間得到的結果和 balancedSpaceThreshold(通過 dfs.datanode.available-space-volume-choosing-policy.balanced-space-threshold 引數進行配置,預設值是 10G) 進行比較。

可用空間策略會以下面三種情況進行處理:

1、如果所有的 volumes 磁碟可用空間都差不多,那麼這些磁碟得到的最大可用空間和最小可用空間差值就會很小,這時候就會使用輪詢磁碟選擇策略來存放副本。

2、如果 volumes 磁碟可用空間相差比較大,那麼可用空間策略會將 volumes 配置中的磁碟按照一定的規則分為 highAvailableVolumes 和 lowAvailableVolumes。具體分配規則是先獲取 volumes 配置的磁碟中最小可用空間,加上 balancedSpaceThreshold(10G),然後將磁碟空間大於這個值的 volumes 放到 highAvailableVolumes 裡面;小於等於這個值的 volumes 放到 lowAvailableVolumes 裡面。

比如我們擁有5個磁碟組成的 volumes,編號和可用空間分別為 1(1G)、2(50G)、3(25G)、4(5G)、5(30G)。按照上面的規則,這些磁碟的最小可用空間為 1G,然後加上 balancedSpaceThreshold,得到 11G,那麼磁碟編號為1、4的磁碟將會放到 lowAvailableVolumes 裡面,磁碟編號為2,3和5將會放到 highAvailableVolumes 裡面。

到現在 volumes 裡面的磁碟已經都分到 highAvailableVolumes 和 lowAvailableVolumes 裡面了。

2.1、如果當前副本的大小大於 lowAvailableVolumes 裡面所有磁碟最大的可用空間(mostAvailableAmongLowVolumes,在上面例子中,lowAvailableVolumes 裡面最大磁碟可用空間為 5G),那麼會採用輪詢的方式從 highAvailableVolumes 裡面獲取相關 volumes 來存放副本。

2.2、剩下的情況會以 75%(通過 dfs.datanode.available-space-volume-choosing-policy.balanced-space-preference-fraction 引數進行配置,推薦將這個引數設定成 0.5 到 1.0 之間)的概率在 highAvailableVolumes 裡面以輪詢的方式 volumes 來存放副本;25% 的概率在 lowAvailableVolumes 裡面以輪詢的方式 volumes 來存放副本。

然而在一個長時間執行的叢集中,由於 HDFS 中的大規模檔案刪除或者通過往 DataNode 中新增新的磁碟仍然會導致同一個 DataNode 中的不同磁碟儲存的資料很不均衡。即使你使用的是基於可用空間的策略,卷(volume)不平衡仍可導致較低效率的磁碟I/O。比如所有新增的資料塊都會往新增的磁碟上寫,在此期間,其他的磁碟會處於空閒狀態,這樣新的磁碟將會是整個系統的瓶頸