Hadoop 文档

General

Common

HDFS

MapReduce

MapReduce REST APIs

YARN

YARN REST APIs

YARN Service

Submarine

Hadoop Compatible File Systems

Auth

Tools

Reference

Configuration

总览

HDFS中的集中式缓存管理是一种显式的缓存机制,允许用户指定HDFS缓存的路径。NameNode将与在磁盘上具有所需块的DataNode通信,并指示它们将这些块缓存在堆外缓存中。

HDFS中的集中式缓存管理具有许多重要的优势。

  1. 显式固定可防止将常用数据从内存中逐出。当工作集的大小超过主内存的大小时,这尤其重要,这对于许多HDFS工作负载来说是很常见的。

  2. 由于DataNode缓存由NameNode管理,因此应用程序可以在制定任务放置决策时查询缓存块位置的集合。将任务与缓存的块副本共置一处可提高读取性能。

  3. 当块已由DataNode缓存后,客户端可以使用新的,效率更高的零拷贝读取API。由于缓存数据的校验和验证是由DataNode一次完成的,因此使用此新API时,客户端实际上可以产生零开销。

  4. 集中式缓存可以提高总体群集内存利用率。当依赖每个DataNode上的OS缓冲区高速缓存时,重复读取一个块将导致该块的所有n个副本都被拉到缓冲区高速缓存中。借助集中式高速缓存管理,用户可以明确地引脚只的的ñ副本,节省了纳米内存。

用例

集中式缓存管理对于重复访问的文件很有用。例如,Hive中的一个小的事实表(通常用于联接)是缓存的不错选择。另一方面,缓存一年报告查询的输入可能不太有用,因为历史数据可能只读取一次。

集中式缓存管理对于具有性能SLA的混合工作负载也很有用。缓存高优先级工作负载的工作集可确保它不与低优先级工作负载的磁盘I / O竞争。

建筑

缓存架构

在这种体系结构中,NameNode负责协调群集中的所有DataNode堆外缓存。NameNode定期从每个DataNode 接收缓存报告,该报告描述了在给定DN上缓存的所有块。NameNode通过piggy带DataNode心跳上的缓存和取消缓存命令来管理DataNode缓存。

NameNode查询其缓存指令集,以确定应该缓存哪些路径。缓存指令永久存储在fsimage和编辑日志中,并且可以通过Java和命令行API进行添加,删除和修改。NameNode还存储一组缓存池,这是用于将缓存指令组合在一起以进行资源管理和强制执行权限的管理实体。

NameNode定期重新扫描名称空间和活动缓存指令,以确定哪些块需要缓存或取消缓存,并将缓存工作分配给DataNodes。还可以通过用户操作(例如添加或删除缓存指令或删除缓存池)来触发重新扫描。

我们目前不缓存正在构造,损坏或不完整的块。如果缓存指令涵盖了符号链接,则不会缓存符号链接目标。

缓存当前在文件或目录级别完成。块和子块缓存是将来的工作。

概念

缓存指令

一个缓存指令定义应该缓存的路径。路径可以是目录或文件。目录以非递归方式缓存,这意味着仅目录的第一级列表中的文件。

指令还指定其他参数,例如高速缓存复制因子和到期时间。复制因子指定要缓存的块副本的数量。如果多个缓存指令引用同一文件,则将应用最大缓存复制因子。

到期时间在命令行上指定为生存时间(TTL)即将来的相对到期时间。缓存指令到期后,NameNode在制定缓存决策时将不再考虑该指令。

缓存池

一个高速缓存池是用来管理缓存指令组的管理实体。高速缓存池具有类似UNIX的权限,该权限限制了哪些用户和组有权访问该池。写入权限允许用户向池添加和删除高速缓存指令。读取权限使用户可以列出池中的缓存指令以及其他元数据。执行权限未使用。

缓存池也用于资源管理。池可以强制执行最大限制,该限制限制了池中的指令可以聚合总计缓存的字节数。通常,池限制的总和将大约等于为群集上的HDFS缓存保留的聚合内存量。缓存池还跟踪大量统计信息,以帮助集群用户确定什么是和应该缓存什么。

池还可以规定最长生存时间。这限制了将指令添加到池中的最大到期时间。

cacheadmin命令行界面

在命令行上,管理员和用户可以通过hdfs cacheadmin子命令与缓存池和指令进行交互。

高速缓存指令由唯一的,非重复的64位整数ID标识。即使以后删除了缓存指令,ID也不会被重用。

高速缓存池由唯一的字符串名称标识。

缓存指令命令

addDirective

用法:hdfs cacheadmin -addDirective -path <路径> -pool <池名称> [-force] [-复制<复制>] [-ttl <生存时间>]

添加一个新的缓存指令。

<路径> 缓存路径。路径可以是目录或文件。
<池名称> 指令将添加到的池。您必须对高速缓存池具有写权限才能添加新指令。
-力 跳过对缓存池资源限制的检查。
<复制> 要使用的缓存复制因子。默认为1。
<生存时间> 指令有效的时间。可以以分钟,小时和天为单位指定,例如30m,4h,2d。有效单位为[smhd]。“从不”表示永不过期的指令。如果未指定,则该指令永不过期。

removeDirective

用法:hdfs cacheadmin -removeDirective <id>

删除缓存指令。

<id> 要删除的缓存指令的ID。您必须对指令池具有写许可权才能将其删除。要查看高速缓存指令ID的列表,请使用-listDirectives命令。

removeDirectives

用法:hdfs cacheadmin -removeDirectives <路径>

删除具有指定路径的每个缓存指令。

<路径> 要删除的缓存指令的路径。您必须对指令池具有写许可权才能将其删除。要查看高速缓存指令的列表,请使用-listDirectives命令。

listDirectives

用法:hdfs cacheadmin -listDirectives [-stats] [-path <路径>] [-pool <pool>]

列出缓存指令。

<路径> 仅列出具有此路径的缓存指令。请注意,如果在缓存池中存在我们没有读取访问权限的路径的缓存指令,则不会列出该指令。
<池> 仅列出该池中的路径缓存指令。
统计 列出基于路径的缓存指令统计信息。

缓存池命令

addPool

用法:hdfs cacheadmin -addPool <名称> [-所有者<所有者>] [-组<组>] [-模式<模式>] [-限制<限制>] [-maxTtl <maxTtl>]

添加一个新的缓存池。

<名称> 新池的名称。
<所有者> 池所有者的用户名。默认为当前用户。
<组> 池组。默认为当前用户的主要组名。
<模式> 池的UNIX样式权限。权限以八进制指定,例如0755。默认情况下,此设置为0755。
<限制> 总的来说,此池中的指令可以缓存的最大字节数。默认情况下,未设置限制。
<maxTtl> 将指令添加到池中的最大允许生存时间。可以以秒,分钟,小时和天为单位指定,例如120s,30m,4h,2d。有效单位为[smhd]。默认情况下,未设置最大值。值“从不”表示没有限制。

ModifyPool

用法:hdfs cacheadmin -modifyPool <名称> [-所有者<所有者>] [-组<组>] [-模式<模式>] [-限制<限制>] [-maxTtl <maxTtl>]

修改现有缓存池的元数据。

<名称> 要修改的池的名称。
<所有者> 池所有者的用户名。
<组> 池组的组名。
<模式> 八进制的池的Unix样式权限。
<限制> 此池可以缓存的最大字节数。
<maxTtl> 将指令添加到池中的最大允许生存时间。

removePool

用法:hdfs cacheadmin -removePool <名称>

删除缓存池。这还将取消缓存与池关联的路径。

<名称> 要删除的缓存池的名称。

listPools

用法:hdfs cacheadmin -listPools [-stats] [<名称>]

显示有关一个或多个缓存池的信息,例如名称,所有者,组,权限等。

统计 显示其他缓存池统计信息。
<名称> 如果指定,则仅列出命名的缓存池。

帮帮我

用法:hdfs cacheadmin -help <命令名>

获取有关命令的详细帮助。

<命令名称> 获得详细帮助的命令。如果未指定命令,则为所有命令打印详细的帮助。

组态

本地图书馆

为了将阻止文件锁定到内存中,DataNode依赖Windows上libhadoop.sohadoop.dll中的本机JNI代码。如果您正在使用HDFS集中式缓存管理,请确保启用JNI

配置属性

需要

确保配置以下内容:

  • dfs.datanode.max.locked.memory

    这确定了DataNode将用于缓存的最大内存量。在类似Unix的系统上,还需要增加DataNode用户的“内存大小” ulimit(ulimit -l)以匹配此参数(请参阅下面的“ OS Limits”部分)。设置此值时,请记住,您还将需要内存中的空间来做其他事情,例如DataNode和应用程序JVM堆以及操作系统页面缓存。

    此设置与“ 惰性持久写入”功能共享。数据节点将确保“惰性持久写入”和“集中式缓存管理”使用的组合内存不超过dfs.datanode.max.locked.memory中配置的数量。

可选的

以下属性不是必需的,但可以指定用于调整:

  • dfs.namenode.path.based.cache.refresh.interval.ms

    NameNode会将其用作后续路径缓存重新扫描之间的毫秒数。这将计算要缓存的块,以及每个DataNode包含应缓存它的块的副本。

    默认情况下,此参数设置为30000,即30秒。

  • dfs.datanode.fsdatasetcache.max.threads.per.volume

    DataNode将以此为每个卷用于缓存新数据的最大线程数。

    默认情况下,此参数设置为4。

  • dfs.cachereport.intervalMsec

    DataNode将以此为单位,将其缓存状态的完整报告发送到NameNode之间的毫秒数。

    默认情况下,此参数设置为10000,即10秒。

  • dfs.namenode.path.based.cache.block.map.allocation.percent

    我们将分配给缓存块映射的Java堆的百分比。缓存的块映射是使用链式哈希的哈希映射。如果缓存的块数量很大,访问较小的映射可能会比较慢。较大的地图会占用更多内存。默认值为0.25%。

  • dfs.namenode.caching.enabled

    此参数可用于启用/禁用NameNode中的集中式缓存。禁用集中式缓存后,NameNode将不会处理缓存报告或在群集上存储有关块缓存位置的信息。请注意,NameNode将继续在文件系统元数据中存储基于路径的缓存位置,即使在启用缓存之前它不会对该信息起作用。此参数的默认值为true(即启用集中式缓存)。

操作系统限制

如果收到错误“由于已配置的最大锁定内存大小而导致无法启动数据节点…大于数据节点的可用RLIMIT_MEMLOCK ulimit”,则表示操作系统对您可以锁定的内存量施加的限制比您所限制的要低。已经配置。要解决此问题,您必须调整与DataNode一起运行的ulimit -l值。通常,此值在/etc/security/limits.conf中配置。但是,它会根据所使用的操作系统和发行版而有所不同。

您可以从外壳程序运行ulimit -l并获得比使用dfs.datanode.max.locked.memory或字符串“ unlimited” 配置的更高的值时,已经正确配置了该值。表示没有限制。请注意,通常ulimit -l以KB为单位输出内存锁定限制,但是dfs.datanode.max.locked.memory必须以字节为单位指定。

此信息不适用于Windows上的部署。Windows没有ulimit -l的直接等效项。