几句话聊聊HDFS的异构存储策略
在设计海量数据的存储架构时,我们往往会面临成本和速率方面的抉择:普通HDD容量大且廉价,但读写速率较慢;SSD的读写比HDD要快数倍到十数倍,但是成本高,单位成本的容量小。所以,当数据量大到一定程度之后,几乎都要考虑冷热数据分离的存储架构,正式的称呼为异构存储(heterogeneous storage)。本文简要介绍HDFS的异构存储策略。
从Hadoop 2.6.0(HDFS-2832)开始,HDFS正式开始支持异构存储,即DataNode的存储不再是统一的,而是多种不同存储介质的集合。Hortonworks的PPT里有一页图示如下。
HDFS支持的存储介质(storage type)有以下4种:
- RAM_DISK(内存);
- SSD(固态硬盘);
- DISK(机械硬盘/HDD);
- ARCHIVE(归档存储,可以理解为比HDD还慢,但不易失的超大容量介质)。
显然,它们的读写速率是由快到慢的,所以前两者适合热数据的存储,后两者适合冷数据的存储。当然,DataNode不会自动探知各个存储路径属于哪种介质,所以在配置dfs.datanode.data.dir
参数时,需要手动加上前缀,如:/data1/dfs/dn,[SSD]/data2/dfs/dn
。如果不加前缀,默认为DISK。
只设定了存储介质还不够,HDFS又定义了6种存储策略(storage policy),以适应多副本存储的特性,通过设定dfs.storage.policy.enabled
参数来启用(默认就是启用的),列举如下:
- Lazy_Persist:1个副本存储在内存,其余n-1个副本存储在HDD;
- All_SSD:所有副本存储在SSD;
- One_SSD:1个副本存储在SSD,其余n-1个副本存储在HDD;
- Hot(默认值):全部副本存储在HDD;
- Warm:1个副本存储在HDD,其余n-1个副本归档存储;
- Cold:全部副本归档存储。
可见,HDFS的异构存储策略比单纯的冷热区分得更加细致。通过以下命令可以查看支持的存储策略列表。
~ hdfs storagepolicies -listPolicies
Block Storage Policies:
BlockStoragePolicy{COLD:2, storageTypes=[ARCHIVE], creationFallbacks=[], replicationFallbacks=[]}
BlockStoragePolicy{WARM:5, storageTypes=[DISK, ARCHIVE], creationFallbacks=[DISK, ARCHIVE], replicationFallbacks=[DISK, ARCHIVE]}
BlockStoragePolicy{HOT:7, storageTypes=[DISK], creationFallbacks=[], replicationFallbacks=[ARCHIVE]}
BlockStoragePolicy{ONE_SSD:10, storageTypes=[SSD, DISK], creationFallbacks=[SSD, DISK], replicationFallbacks=[SSD, DISK]}
BlockStoragePolicy{ALL_SSD:12, storageTypes=[SSD], creationFallbacks=[DISK], replicationFallbacks=[DISK]}
BlockStoragePolicy{LAZY_PERSIST:15, storageTypes=[RAM_DISK, DISK], creationFallbacks=[DISK], replicationFallbacks=[DISK]}
其中,creationFallbacks和replicationFallbacks分别指存储策略对应的介质空间不足时,会fallback到哪种介质做写入和复制。
通过以下命令可以为一个HDFS上的目录设置或者取消存储策略。
# 例:为HBase的WAL设置纯SSD的存储策略
hdfs storagepolicies -setStoragePolicy -path /hbase/wal -policy All_SSD
# 取消存储策略
hdfs storagepolicies -unsetStoragePolicy -path /hbase/wal
注意,设置存储策略会影响所有子目录,而取消存储策略会将当前目录的存储策略重置为与其父目录相同。当然,也可以获取到某目录当前的存储策略。
hdfs storagepolicies -getStoragePolicy -path /hbase/wal
设置好之后,当客户端向NameNode发送写请求时,NameNode就会根据配置好的存储介质和存储策略选择相应的DataNode进行写入。DataNode通过在心跳包中携带存储介质和存储策略的数据来保持NameNode的感知。
最后,如果我们修改了HDFS目录的存储策略,还可以通过hdfs mover
命令来转移不符合存储策略的数据,不再赘述。
我们当前在深入研究的ClickHouse同样支持异构存储,完全根据配置文件来设置,更加灵活。官方文档写得已经足够详细,看官可参考。
明天继续搬砖,晚安吧各位。