前言
總體上HDFS異構存儲的價值在於,根據數據熱度采用不同策略從而提升集群整體資源使用效率。
對於頻繁訪問的數據,將其全部或部分保存在更高訪問性能的存儲介質(內存或SSD)上,提升其讀寫性能;
對於幾乎不會訪問的數據,保存在歸檔存儲介質上,降低其存儲成本。
但是HDFS異構存儲的配置需要用戶對目錄指定相應的策略,即用戶需要預先知道每個目錄下的文件的訪問熱度(事先划分好冷熱數據存儲目錄,設置好對應的Storage Policy,
然后后續相應的程序在對應分類目錄下寫數據,自動繼承父目錄的存儲策略),在實際大數據平台的應用中,這是比較困難的一點。
一、異構存儲是什么
所謂的異構存儲就是將不同需求或者冷熱的數據存儲到不同的介質中去,實現既能兼顧性能又能兼顧成本。對於存儲到HDFS的數據大致可以分下圖的4個等級。

如果將這部分數據存儲通過高壓縮比,並且存儲到普通的SATA大容量盤中去,能極大地節約成本。
對於熱數據和實時數據,寫請求比較高,讀請求也很高,但是數據量很小。這個時候為了實現高並發低延遲,我們可以將這部分數據保存到SSD中。
Hadoop從2.6.0版本開始支持異構存儲,HBase也從1.1.0開始支持將WAL的異構存儲策略。
備注:這里面的難點是要對業務訪問模式有足夠的了解,提前確認好各個目錄下的數據訪問熱度,以便規划好數據的存儲策略。
二、HDFS異構存儲類型和策略
存儲類型
HDFS異構存儲支持如下4種類型,分別是:
- RAM_DISK
- SSD
- DISK
- ARCHIVE
/data1/hbase/hdfs,/data2/hbase/hdfs,/data3/hbase/hdfs,/data4/hbase/hdfs,/data5/hbase/hdfs,/data6/hbase/hdfs,
/data7/hbase/hdfs,/data8/hbase/hdfs,/data9/hbase/hdfs,/data10/hbase/hdfs,/data11/hbase/hdfs,/data12/hbase/hdfs,
[SSD]/wal_data
這里前面12個盤都沒有指定存儲類型,則默認是DISK存儲,而第13快盤指定了SSD存儲類型。
這4種存儲類型,按照RAM_DISK->SSD->DISK->ARCHIVE,速度由快到慢,單位存儲成本由高到低。
存儲策略
HDFS存儲策略設置如下表:

由上圖,我們可以看出HDFS總共支持Lazy_Persist、All_SSD、One_SSD、Hot、Warm和Cold等6種存儲策略,默認策略為Hot。
上圖中的第三列是表示存儲策略對應的存儲類型,具體如下:
- Lazy_Persist : 1份數據存儲在[RAM_DISK]即內存中,其他副本存儲在DISK中
- All_SSD:全部數據都存儲在SSD中
- One_SSD:一份數據存儲在SSD中,其他副本存儲在DISK中
- Hot:全部數據存儲在DISK中
- Warm:一份數據存儲在DISK中,其他數據存儲方式為ARCHIVE
- Cold:全部數據以ARCHIVE的方式保存
上圖中的第4、5列表示創建和寫副本的時候,如果該存儲策略對應的資源不足,比如磁盤不可用或者空間寫滿,則創建文件和同步副本的時候選擇第4和第5列對應的存儲類型,你可以理解為降級機制。
三、HDFS異構存儲原理
對於HDFS異構存儲的原理大致概括如下圖所示:

這里的原理簡單概括如下:
1、在hdfs的配置文件hdfs-site.xml中配置對應的異構存儲(后面配置部分有詳細介紹)
2、DataNode啟動的時候從配置文件中讀取對應的存儲類型,以及容量情況,並通過心跳的形式不斷的上報給NameNode。
3、NameNode收到DataNode發送的關於存儲類型、容量等內容的心跳包后,會進行處理,更新存儲的相關內容。
4、寫請求發到NameNode后,NameNode根據寫請求具體的目錄對應的存儲策略選擇對應的存儲類型的DataNode進行寫入操作。
備注:上面是根據自己的理解簡單概括的大致調用過程,如果需要了解更詳細的調用關系,可以閱讀這篇文章,寫得很詳細:https://blog.csdn.net/androidlushangderen/article/details/51105876
四、HDFS異構存儲的配置和策略設置
HDFS異構存的配置
每個磁盤單獨掛載到不同目錄,需要注意加上 noatime 選項。 首先配置 DataNode 的數據目錄,只需要將對應的類型添加到dfs.datanode.data.dir的配置項中即可,
備注:也需要配置dfs.storage.policy.enabled為true,因為默認就是true,所以這里忽略。
配置的時候需要申明存儲類型和對應的目錄,存儲類型需要用中括號括起來,存儲類型有[SSD]/[DISK]/[ARCHIVE]/[RAM_DISK],如果不指定存儲類型,則默認就是DISK。
比如我的機器中只配置了DISK和SSD的類型,范例如下:

通過上面的例子,前面12個盤,我沒有設置存儲類型,因為都是DISK,最后一個盤使用了SSD類型。
HDFS異構存儲策略設置
HDFS提供了專門的命令來設置對應的策略,命令使用方法如下:
查看策略幫助信息:
hdfs storagepolicies -help
列出當前版本支持的存儲策略:
hdfs storagepolicies -listPolicies
設置對應路徑的策略:
hdfs storagepolicies -setStoragePolicy -path -policy
范例:
# 設置/hbase/data/default為Hot的策略
hdfs storagepolicies -setStoragePolicy -path /hbase/data/default -policy Hot
# 取消策略
hdfs storagepolicies -unsetStoragePolicy -path
# 獲取對應路徑的策略
hdfs storagepolicies -getStoragePolicy -path
五、HDFS異構存儲的管理
對於HDFS異構存儲的管理,主要包含如下兩個方面:
1、統計線上數據的訪問頻率,確認冷熱數據所在目錄,灰度進行調整
2、使用hdfs storagepolicies相關命令進行策略的調整
3、修改存儲策略以后,使用mover工具進行數據的遷移,mover的使用方法如下:
hdfs mover [-p files/dirs | -f localfile ]
可以使用-p指定要遷移的目錄,也可以將要遷移的文件列表寫入文件中,用-f參數指定對應的文件或者目錄進行遷移。
六、Move遷移數據
Mover 是 HDFS 的一個數據遷移工具,類似 Balancer. 區別在於,Mover 的目的是把數據塊按照存儲策略遷移,Balancer 是在不同 DataNode 直接進行平衡。
如果 DataNode 掛載了多種存儲類型,Mover 優先嘗試在本地遷移,避免網絡 IO.
使用方式: hdfs mover -p <path>,如果想一次性遷移所有數據,可把 path 指定為根路徑,不過需要的時間也更長。
七、HDFS 社區版存在問題:
- 對存量數據處理的支持不好。設置數據的 Storage Policies 屬性后,只對新寫入的數據有效。對於存量數據,系統並不能將其自動移動到對應的存儲介質上。
-
沒有提供冷數據分析方案。
-
沒有提供把遠程存儲設備(譬如 S3)mount 到 DataNode 上作為存儲類型的方案。
八、HBase利用HDFS異構存儲特性
HBase 資源隔離 + 異構存儲。SATA 磁盤的隨機 iops 能力,單次訪問的 RT,讀寫吞吐上都遠遠不如 SSD,那么對 RT 極其敏感業務來說,SATA 盤並不能勝任,所以我們需要 HBase 有支持 SSD 存儲介質的能力。
為了 HBase 可以支持異構存儲,首先在 HDFS 層面就需要做響應的支持,在 HDFS 2.6.x 以及之后的版本,提供了對 SSD 上存儲文件的能力,
換句話說在一個 HDFS 集群上可以有 SSD 和 SATA 磁盤並存,對應到 HDFS 存儲格式為 [ssd] 與 [disk]。
存儲架構
添加 SSD 磁盤之后,HDFS 集群存儲架構示意圖:

使用場景
- 將WAL日志保存到SSD中,其他的數據則存儲在普通的SATA盤中
HBase實現異構wal存儲很簡單,底層依賴的就是hdfs的異構storage策略,不過是將wal文件所在的目錄經反射調用dfs client的setStoragePolicy方法設置為用戶指定的policy。
具體的配置策略如下:在 hdfs-site.xml 中修改:
<property>
<name>hbase.wal.storage.policy</name>
<value>ONE_SSD</value>
</property>
該配置的默認值是NONE,也就是wal文件和數據都存儲在DISK上,不做區分。
可以修改為ONE_SSD或者ALL_SDD,不同在於:
- ONE_SSD:wal的一個副本置於SSD上,而其他副本仍然在默認存儲;
- ALL_SSD:wal文件的所有副本都存儲於SSD盤上;
- 將表的指定列族數據存儲在SSD盤中
在HBASE-14061之后,我們支持通過 hbase.hstore.block.storage.policy 配置,我們支持CF級別設置來覆蓋配置文件中的設置。
例如,要創建具有兩個系列的表:具有“ ALL_SSD”存儲策略的“ cf1”和具有“ ONE_SSD”的“ cf2”,我們可以在hbase shell中使用以下命令:
create 'table',{NAME=>'f1',STORAGE_POLICY=>'ALL_SSD'},{NAME=>'f2',STORAGE_POLICY=>'ONE_SSD'}
我們還可以像其他所有配置一樣在table屬性中設置配置:
create 'table',{NAME=>'f1',CONFIGURATION=>{'hbase.hstore.block.storage.policy'=>'ONE_SSD'}}
