client 通过TCP 连接datanode,并通过DTP(DataTransferProtocol)传输数据。
这种模式有一个问题就是:datanode需要维护一个线程并为每个client打开socket建立连接传输数据。
从linux内核角度来看tcp协议是有开销的,同时DTP也有开销。
于是就出现了“Secure short-circuit local reads" 简称(SCLR)
从HDFS-2246提到过short-circuit local reads 优化。
大体思路: 因client和数据在同一个node,所以没必要去和datanode建立TCP连接。client本身就从本地磁盘读取数据。
这个设置,当然也有一些配置上的麻烦。Ops必须改变DN数据目录权限。允许客户端打开相关文件。
还需要定义一个白名单用户,可以使用这个特性。其他用户不需要。
另外带来的风险是,有安全漏洞,有权限的用户可以直接浏览所有数据。
HDFS-347 让SCLR 安全.
HDFS-2246 将所有的数据开放给客户端, 上面提到的问题。
恰好Unix提供了一种机制文件描述符, HDFS-347可以使用该机制安全的short-circuit local reads。
当client向datanode请求数据的时候,datanode打开blockfile和元数据文件,并直接传给client,而不是将路径传给client。因为文件描述符是只读的,client不能修改读到的数据,同时也不支持对block所在路径的访问。也就不能访问其他数据了。
Cache 文件描述符
HDFS Client需要经常读取相同的block文件,特别是像HBbase.为了提高该场景下的本地读。
HDFS-2246实现的机制中有一个block路径的cache,cache允许客户端重新打开block文件,而不需要再去访问datanode。
相对于路径的cache,新的机制实现了一个FileInputStreamCache 缓存文件描述符。 其优点是不需要client重新代开文件。其性能优于老的读取机制
cache的大小可以通过dfs.client.read.shortcircuit.cache.size 调整,cache超时通过dfs.client.read.shortcircuit.streams.cache.expiry.ms设置。当然也可以关掉该cache,设置它的值为0即可。多数情况下,默认配置即可。如果是特殊的大规模的工作集和高文件描述符限制,可以调整试下。
HDFS-347 实现的新机制,所有hdfs用户都可以使用该特性,而不是局限于配置的几个用户。也没有必要去修改Unix用户组来设定谁可以访问DN路径。然而,java标准库并不包含支持文件描述符传递的库,所以该特性需要使用JNI。同时需要安装libhadoop.so库.
同时它也需要一个unix套接字路径,可以设置dfs.domain.socket.path。这个路径必须安全地阻止无优先级进程进行MITM攻击(Man-in-the-middle attrack). 每个套接字必须是root或者datanode用户所有,不能是人人都可以读写的路径。
参考链接:
http://www.importnew.com/6151.html