HADOOP之HDFS 的数据管理与策略选择----HDFS 中心缓存管理(2)

HDFS 中心缓存管理

     中心缓存管理器(CacheManager)和缓存块监控服务(CacheReplicationMonitor)

适用场景、中心缓存管理的原理、命令使用。

1.HDFS 缓存适用场景

  1. 公共资源文件
  2. 短期临时的热 数据文件

2.HDFS 缓存的结构设计

 

          

                                                                                  图 HDFS缓存总结构关系

     CacheDirective是缓存的基本单位,可以是目录或文件。

     CachePool管理信息有:缓存池名称,所属用户名、组名,缓存池权限最大缓存字节数,过期时间,缓存对象列表等信息。

3.HDFS 缓存管理机制分析

  1. CacheAdmin CLI 命令在 CacheManager 的实现

三种映射关系:

//CacheDirective id对CacheDirective 的映射关系

private final TreeMap<Long, CacheDirective> directivesByid =

                               new TreeMap<Long, CacheDirective>();

//缓存路径对 CacheDirective 列表的映射关系,说明一个文件/目录路径可以同时被多次缓存

private final TreeMap<String , List<CacheDirective> directivesByPath =

                               new TreeMap<String, List<CacheDirective>();

//缓存池名称对 Cache Pool 的映射

private final TreeMap<String, CachePool> cachePools =

                               new TreeMap<String, CachePool>();

CacheManager通过id到CacheDirective,路径到CacheDirective列表和名称到CachePool的多个映射关系,使得原本逻辑上的父子关系结构平级化了,方便了多条件地灵活查询。

  1. CacheReplicationMonitor 缓存监控服务

     《Hadoop HDFS深度剖析》见第二章中1.5中的内容

 

4.HDFS 中心缓存疑问点

两个疑问点:

    第一个疑问点, CacheManager#checkLimit 方法在运行的时候默认副本数总是为1。在checkLimit 的前面部分用副本数计算字节需求量,但其实在 computeNeeded 方法中副本数并没有被用上。

在上面注释的地方如果没有用上副本数,就会导致后面异常时输出的信息有误。执行过程如下:

private void checkLimit(CachePool pool , Str ng path,
		short replication) throws InvalidRequestException {
	//副本数作为参数传入,用以计算统计值,但是没有被用上
	CacheDirectiveStats stats = computeNeeded(path, replication);
	if (pool.getLimit() == CachePoolinfo.LIMIT_UNLIMITED) {
		return;
	}
	//因为副本数没用上,在这里需要乘上副本系数
	if (pool.getBytesNeeded() + (stats. getBytesNeeded() * replication) > pool.getLimit()) {
		//但是在下面的输出中又除了副本数,因此副本数并没有乘上
		throw new InvalidRequestException ( " Caching path " + path +" of size
		+ stats.getBytesNeeded() / replication + " bytes at replication "
		+ replication +" would exceed pool " + pool.getPoolName()
		+ " 's remaining capacity of "
		+ (pool.getLimit() - pool.getBytesNeeded()) + " bytes.");
}
}

这个问题已确认是一个 bug ,在社区上已有相应 JIRA : HDFS-10448 ( CacheManager#

checkLimit always assumes a replication factor of 1).

 

第二个疑问点, CacheReplicationMonitor 在缓存目录的时候没有考虑到子目录的情况,只是处理了直接孩子文件的情况,代码如下:

private void rescanCacheDirectives() {
		FSDirectory fsDir = namesystem.getFSDirectory();
		final long now= new Date().getTime();
		//遍历缓存管理器中需要缓存的基本单元
		for (CacheDirective directive : cacheManager.getCacheDirectives()) {
			// ...
			if(node == null) {
				LCG debug ("Directive {} : No inode found at {} ”, directive.getid(), path);
			} else if (node.isDirectory()) {
				//如果此对象包含的工Node 是目录的话 则遍历孩子节点
				INodeDirectory = node.asDirectory();
				ReadOnlyList<INode> children = dir.getChildrenList(Snapshot.CURRENT_STATE_ID);
				for (INode child : children) {
					if (child.isFile()) {
						rescanFile(directive, child.asFile());
					}
					//这里缺少了孩子是目录的情况
				}
			} else if (node.isFile()) {
				//如果此对象包含的INode是纯文件,则直接进行处理
				rescanFile(directive, node.asFile());
			} else {
				LOG.debug("Directive{} : ignor ng non-directive on-file inode {}",directive.getid(), node);
			}
		}
	}

    后来笔者看了官网的介绍,目前的版本中只对缓存路径下的第 层孩 做处理,并没有做到对路径的递归处理。递归处理缓存路径是对这种情况的一个优化,目前社区已有相应的 JIRA 来完善这一点: HDFS-10594 ( HDFS-4949 should support recursive cache directives ),感兴趣的同学可以关注一下这个 JIRA。

 

5.HDFS CacheAdmin 命令使用

$hdfs cacheadmin

Usage: bin/hdfs cacheadmin [COMMAND]

          [-addDirective -path <path> -pool <pool-name> [-force] [-replication <replication>] [-ttl <time-to-live>]]

          [-modifyDirective -id <id> [-path <path>] [-force] [-replication <replication>] [-pool <pool-name>] [-ttl <time-to-live>]]

          [-listDirectives [-stats] [-path <path>] [-pool <pool>] [-id <id>]

          [-removeDirective <id>]

          [-removeDirectives -path <path>]

          [-addPool <name> [-owner <owner>] [-group <group>] [-mode <mode>] [-limit <limit>] [-maxTtl <maxTtl>]

          [-modifyPool <name> [-owner <owner>] [-group <group>] [-mode <mode>] [-limit <limit>] [-maxTtl <maxTtl>]]

          [-removePool <name>]

          [-listPools [-stats] [<name>]]

          [-help <command-name>]

                                                                图 HDFS CacheAdmin命令分类图

需要DataNode开启缓存功能开关,默认是关闭的,值为0.

<property>

<name>dfs.datanode.max.locked.memory</name>

<value>0</value>

<description> DataNode 用来缓存块的最大内存空间大小 单位用字节表示 系统变量RLIMIT MEMLOCK 至少需要设置得比此配置值要大 否则 DataNode 会出现启动失败的现象 在默认的情况下,此配置值为 表明默认关闭内存缓存的功能</description>

</property>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值