谈笑间学会HDFS—HDFS的数据管理与策略选择

HDFS缓存与缓存块

HDFS的缓存与我们平常所说的缓存(cache)在作用上是一致的,主要是为了减少重复的数据请求过程。但是在具体实现上,我们平常所用的缓存可能只由一个简单的缓冲数组构成,而HDFS用的是缓存块(cacheblock)的概念。HDFS的缓存块由普通的文件块转换而来,同样也可以转换回去。HDFS缓存的出现可以大大提高用户读取文件的速度,因为它是缓存在DataNode内存中的,此过程无需进行读取磁盘的操作。

HDFS物理层面缓存块

物理层面缓存块这个词在HDFS源码中的解释如下:“利用mmap、mlock这样的系统调用将块数据锁入内存,以此达到在DataNode上缓存数据的效果。”大意为利用mmap、mlock系统调用将块锁入内存。没接触过底层操作系统知识的人可能不是很清楚mmap、mlock调用是怎么一回事,下面简单介绍一下。mmap系统调用,它是一个内存映射调用。mmap主要作用是将一个文件或者其他对象映射进内存。将文件或其他对象映射进内存。

缓存块的生命周期状态

缓存块的生命周期不仅仅只有Cached(已缓存)和UnCached(未缓存)两种。从源码中可以看出

Cache状态信息总共分为四类:

  • CACHING     表示块正在被缓存。

  • CACHING_CANCELLED   正在被缓存的块已处于被取消的状态。

  • CACHED    表明数据块已被缓存。

  • UNCACHING    表明缓存块正处于取消缓存的状态。

HDFS缓存相关配置

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

这个配置项的名称与实际所使用的功能情况不太一致,有点歧义的感觉,可能叫dfs.datanode.max.cache.memory比较好理解一些。

注意·

        第一点,此配置项会受系统最大可使用内存大小(RLIMIT_MEMLOCK)的影响,造成启动DataNode失败的现象,会有如下的错误输出:

上面的记录表明操作系统不能提供相应大小的内存,可以通过ulimit–l<value>命令对此进行调整。一般而言,这个值是在/etc/security/limits.conf文件中配置的。

第二点,此配置项并不是HDFS缓存机制所独有的,它与HDFS的LAZY_PERSIST策略会共享dfs.datanode.max.locked.memory配置。换句话说,如果用于LAZY_PERSIST的存储数据块多了,那么HDFS缓存所能使用的空间自然就会变少。

最后附上几个与HDFS缓存相关的配置参数:

  • dfs.datanode.fsdatasetcache.max.threads.per.volume:用于缓存块数据的最大线程数,这个线程数是针对每个存储目录而言,默认值为4。
  • dfs.cachereport.intervalMsec:缓存块上报间隔,默认10秒。

HDFS缓存功能默认是关闭的,可以通过配置dfs.datanode.max.locked.memory的值来开启此功能,对于文件数据的读性能将会带来不小的提升。

HDFS缓存适用场景

缓存HDFS中的热点公共资源文件和短期临时的热点数据文件。

第一种场景:公共资源文件。这些文件可以是一些存放于HDFS中的依赖资源jar包,或是一些算法学习依赖的.so文件等。像这类数据文件,放在HDFS上的好处是我们可以在HDFS上全局共享,不用依赖本地机器的资源文件。此外这种做法易于管理,如果想要进行资源包的升级,可以直接更新到HDFS上。但是这种场景更好的做法是把它做成分布式缓存,否则在程序中将会发送大量的请求到NameNode中去获取这些资源文件的内容。而且这种请求量是非常恐怖的,不是说请求一次就够了,而是使用一次就请求一次。

第二种场景:短期临时的热点数据文件。比如集群中每天运行统计的报表数据,需要读取前一天的或是最近一周的数据做离线分析。但是超出这个期限内的数据基本就很少再用到了,就可以视为冷数据了。那么这个时候我们就可以把符合这个时间段的数据做缓存处理,如果数据过期了,就直接从缓存中清除。

以上两种情况,都是HDFS缓存非常适用的场景。

缓存总结构图

HDFSCacheAdmin命令使用

HDFS中用于缓存块操作的相关命令使用。这些命令都集中在hdfscacheadmin命令下,在Hadoop客户端中输入如下指令,就会弹出所有使用命令:

{14:16}~ ➭ hdfs cacheadmin
Usage: bin/hdfs cacheadmin [COMMAND] # 以下为hdfscacheadmin的所有使用命令
          [-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>] # 删除指定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>]  # 查阅具体某条命令的使用帮助信息

以上命令中除了最后一个help帮助命令之外,其余9个命令都与缓存操作相关。在这些命令中,还可以划分为两大类:一类是CachePool相关命令,另一类是CacheDirective相关命令。分类图如下图所示。

HDFS快照管理

快照的概念

在分析HDFS内部的快照管理之前,需要先了解快照的概念。首先有一个根本的原则:“快照不是数据的简单拷贝,快照只做差异的记录。

这一原则在其他很多系统的快照概念中都是适用的,比如磁盘快照,也是不保存真实数据的。因为不保存实际的数据,所以快照的生成往往非常迅速。在HDFS中,如果在其中一个目录比如/A下创建一个快照,则快照文件中将会存在与/A目录下完全一致的子目录文件结构以及相应的属性信息,通过fscat命令也能看到里面具体的文件内容。但是这并不意味着快照已经对此数据进行完全的拷贝。这里遵循一个原则:对于大多不变的数据,你所看到的数据其实是当前物理路径所指的内容,而发生变更的INode数据才会被快照额外拷贝,也就是前面所说的差异拷贝。

HDFS快照相关命令

一个快照目录下可以有多个快照文件,快照目录可以创建、删除自身目录下的快照文件,同时快照目录本身又被快照目录管理器所管理。这里面就引出了更深层次的内容:HDFS内部的快照管理机制。

快照结构关系(源码)

1、快照管理器管理多个快照目录

其实每个快照目录就是我们非常熟悉的INodeDirectory类。

2、一个快照目录拥有多个快照文件。快照在快照目录中的存放不是很明显,它是作为一个额外属性存在于INodeDirectory的父类INodeWithAdditionalFields中。INodeWithAdditionalFields内部存放有基本的一些变量属性,例如名称、权限、最近修改时间等等,代码中的定义如下:

快照列表存在于一个叫DirectorySnapshottableFeature的Feature继承类中,源码中的定义如下:

由此可见,快照结构如下:

快照调用流程

快照的调用过程,整个过程以快照管理器(SnapshotManager)作为处理中心。

SnapshotManager负责接收快照操作请求,继而调用相关类进行处理。这里的相关类是INodeDirectory中的Feature继承类。所以全部过程分为如下两部分:

上游请求的接收

请求的下游处理

在上游请求接收阶段中,其接收方式与以往直接接收NameNodeRPC请求的方式略有不同,中间还经过了一层FSDirSnapshotOp类。在这个类中调用了SnapshotManager的操作方法。这样做还是有好处的,可以在FSNamesystem的众多操作里很好地辨别和区分操作的类型。

HDFS快照的使用

HDFS的快照有两大用处,下面是具体的使用场景:

·丢失数据的恢复。这里丢失数据指的是相对于创建快照时间点之后丢失的数据。在HDFS的快照中,只会额外复制发生变更的数据,所以在快照内部,自然会存在丢失数据的一个备份,这个时候只需要将对应快照文件目录拷贝一份即可。

·元数据的差异比较。HDFS的快照能够提供diff比较的功能。比较的结果会展示相对于源端快照,目标快照中发生的文件目录的变更记录。这个差异结果可以用于数据的同步,比如快照在DistCp命令中的使用。用DistCp中的diff参数附加两个from、to快照,进行元数据变更的同步,然后利用DistCp的功能,进行真实数据的拷贝,以此实现集群数据间的同步。这也是HDFS快照的一个很好的使用场景。

当然,HDFS快照还可以有其他使用场景,关键看你怎么去利用这个功能特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MrZhangBaby

请博主喝杯奶茶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值