Hadoop版本:2.6.0
本文系从官方文档翻译而来,转载请尊重译者的工作,注明以下链接:
http://www.cnblogs.com/zhangningbo/p/4146296.html
背景
在HDFS中,通常是通过DataNode来读取数据的。但是,当客户端向DataNode请求读取文件时,DataNode就会从磁盘读取该文件并通过TCP socket将数据发送到客户端。所谓“短路”是指旁路DataNode来读取文件,也就是说,允许客户端直接读取文件。很明显,这种情况只在客户端与数据放在同一地点(译者注:同一主机)时才有可能发生。短路读对于许多应用程序会带来重大的性能提升。
创建
要配置短路本地读,你需要使能libhadoop.so。详见Native Libraries。
短路读利用UNIX域套接字。这是文件系统中的特殊路径,可以让客户端和DataNode通信。你需要设置一个路径给该套接字,而且DataNode要能够创建该路径。另一方面,除了HDFS用户和root用户,其他用户不可能创建该路径。正因如此,所以,通常才使用在/var/run或者/var/lib下的路径。
客户端和DataNode通过在/dev/shm上的一段共享内存来交换信息。
短路本地读需要在DataNode和客户端上同时配置。
所有相关的配置参数
此功能相关的参数主要有以下5个:
属性名称 | 默认值 | 描述 |
dfs.client.read.shortcircuit | false | 该参数打开short-circuit local reads 功能。 |
dfs.domain.socket.path | 可选。该参数是一个指向UNIX域套接字的路径,用于DataNode和本地HDFS客户端通信。如果在该路径中出现了字符串"_PORT",会被替换成DataNode的TCP端口。 | |
dfs.client.read.shortcircuit.skip.checksum | false | 如果设置了该参数,short-circuit local reads功能将跳过checksums校验。通常不推荐这么做,但是该参数对于特殊场合可能有用。如果你在HDFS之外自己做checksum校验,那么就该考虑设置该参数。 |
dfs.client.read.shortcircuit.streams.cache.size | 256 | DFSClient维护着一个用于保存最近已打开的文件描述符的缓存。该参数控制着此缓存的容量。增大该缓存的容量就可以使用更多文件描述符,但是,在涉及大量seek操作的负载上可能带来更好的性能。 |
dfs.client.read.shortcircuit.streams.cache.expiry.ms | 300000 | 该参数控制着文件描述符因为长期不活跃而被关闭之前需要在客户端缓存上下文中驻留的最小时间。 |
以下是示例配置。
<configuration>
<property>
<name>dfs.client.read.shortcircuit</name>
<value>true</value>
</property>
<property>
<name>dfs.domain.socket.path</name>
<value>/var/run/hadoop-hdfs/dn._PORT</value> #官网示例为/var/lib/hadoop-hdfs/dn_socket
</property>
<property>
<name>dfs.client.read.shortcircuit.skip.checksum</name>
<value>false</value>
</property>
<property>
<name>dfs.client.read.shortcircuit.streams.cache.size</name>
<value>1000</value>
</property>
<property>
<name>dfs.client.read.shortcircuit.streams.cache.expiry.ms</name>
<value>10000</value>
</property>
</configuration>
旧版本中的HDFS短路本地读特性
旧版本中实现的短路本地读特性(客户端可以直接在哪个短路本地读套接字上打开HDFS块文件)对于除了linux以外的平台依然可用。通过设置属性dfs.client.use.legacy.blockreader.local和dfs.client.read.shortcircuit为true来使能该特性。
你还需要设置属性dfs.datanode.data.dir.perm为750以替代默认的700,并使用chmod/chown命令改变dfs.datanode.data.dir下的目录树权限为对客户端和DataNode可读。你必须小心谨慎一些,因为这么做就意味着客户端可以旁路HDFS权限来读取所有的块文件。
<configuration>
<property>
<name>dfs.client.read.shortcircuit</name>
<value>true</value>
</property>
<property>
<name>dfs.client.use.legacy.blockreader.local</name>
<value>true</value>
</property>
<property>
<name>dfs.datanode.data.dir.perm</name>
<value>750</value>
</property>
<property>
<name>dfs.block.local-path-access.user</name>
<value>foo,bar</value>
</property>
</configuration>