HDFS 内存存储
用机器的内存作为存储数据的载体。
内存存储策略:LAZY_PERSIST
1.1 HDFS 内存存储原理
问题:数据丢失、内存空间有限。
方案:异步持久化---在内存存储新数据的同时,持久化距离当前时刻最远的数据。
图 LAZY_PERSIST策略原理图
异步存储的大体步骤:
- 对目标文件目录设置StoragePolicy为LAZY_PERSIST的内存存储策略。
- 客户端进程向NameNode发起创建/写文件的请求。
- 客户端请求到具体的DataNode后DataNode会把这些数据块写入RAM内存中,同时启动异步线程服务将内存数据持久化写到磁盘上。
1.2 HDFS的内存存储策略设置
有3种方式:
1.命令行方式
hdfs storagepolicies -setStoragePolicy -path 路径 -policy LAZY_PERSIST
2.调用程序
使用FileSystem抽象类中create文件方法:
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI(“hdfs://ip:port”), conf);
FSDataOutputStream fos = fs.create(path,
FsPermission.getFileDefault(),
EnumSet.of(CreateFlag.CREATE, CreateFlag.LAZY_PERSIST),
bufferLength,
replicationFactor,
blockSize,
null);
图LAZY_PERSIST 策略设置流程图
3. 2.8版本中提供
fs.setStoragePolicy(path, “LAZY_PERSIST”);
LAZY_PERSIST 内存存储
FsDatasetImpl管理DataNode所有磁盘读写的指挥者。
图 LAZY_PERSIST 相关服务对象
RamDiskAsyncLazyPersistService:异步持久化线程服务,最大线程数为1.
LazyWriter:将数据块加入到异步持久化线程池RDALPS中去执行。
RamDiskReplicaLruTracker:副本块跟踪类,维护了已持久化、未持久化副本及总副本数据信息。
1.RamDiskReplicaLruTracker
图 RamDisk 副本块结构关系图
方法分两类:
第一类:异步持久化操作相关方法
图 异步持久化操作相关流程图
第二类:异步持久化操作无关方法
discardReplica:用于移除、撤销内存中的副本
touch:访问一次某特定的副本块,并更新副本块lastUsedTime
getNextCandidateForEviction:当DataNode内存不足,需要更多的空间给新副本块。这里移除的默认策略是LRU策略,可以通过eviction scheme模式设置。
2.LazyWriter
图 LazyWriter 服务流程图
3.RamDiskAsyncLazyPersistService
一个磁盘服务对应一个线程池,并且一个线程池的最大线程数也只有一个。
图 RamDiskAsyncLazyPersistService 方法图
addVolume:加入新的磁盘目录
submitLazyPersistTask:提交执行方法
execute:执行处理的方法,如果失败会重新插入replicateNotPersisted队列中。
4) LAZY_PERSIST 内存存储的使用
第一步:设置内存存储对应类型为RAM_DISK
sudo mount -t tmpfs -o size=16g tmpfs /mnt/dn-tmpfs/
挂载目录并控制使用的内存大小,建议在/etc/fstab文件中写入这个挂载关系。
配置虚拟内存盘到dfs.datanode.data.dir中
例如:
<property>
<name>dfs.datanode.data.dir</name>
<value>/grid/0,/grid/1,/grid/2,[RAM_DISK]/mnt/dn-tmpfs</value>
</property>
其中[RAM_DISK]是必须要的,HDFS默认的都是DISK。
第二步:设置具体的文件策略类型
注意:
- HDFS异构存储策略没有被关闭,默认是开启的,配置项是dfs.storage.policy.enabled.
- 确认dfs.datanode.max.locked.memory是否设置的足够大,是否是datanode能承受。