欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

如何提高hadoop中Short-Circuit Local Reads时的性能及安全性

程序员文章站 2022-06-01 17:36:00
...

本文由 ImportNew - Royce Wong 翻译自 Cloudera。如需转载本文,请先参见文章末尾处的转载要求。 大家都知道,apache hadoop的一个关键思想就是移动计算比移动数据更廉价。所以只要可能,我们就乐忠移动计算到数据地方。因此,HDFS通常使用许多的本地读,在

本文由 ImportNew - Royce Wong 翻译自 Cloudera。如需转载本文,请先参见文章末尾处的转载要求。

大家都知道,apache hadoop的一个关键思想就是移动计算比移动数据更廉价。所以只要可能,我们就乐忠移动计算到数据地方。因此,HDFS通常使用许多的本地读,在本地机器构造读对象读出数据。

如何提高hadoop中Short-Circuit Local Reads时的性能及安全性

最初,hdfs本地读其实和远程读使用的同一种方式:client端通过TCP 连接DN,并通过DataTransferProtocol传输数据。该方法简单,但是有一些不好的地方。例如,DN需要维护一个线程运行,并为每个client打开的tcp套接字建立连接传输数据。在linux内核中tcp协议是有开销的,同时DataTransferProtocol本身也有开销。这里有优化空间。

本文大家将会了解到一项HDFS新的优化,叫做“secure short-circuit local reads”,学习该优化如何实现并怎样提速本地读的。

HDFS-2246 曾经实现的Short-Circuit LocalReads

HDFS-2246,ndrew Purtell, Suresh Srinivas, Jitendra Nath Pandey, and Benoy Antony等人添加了一项称为“short-circuit local reads”优化。

其关键思想如下:因为客户端和数据在同一个节点,所以没必要再去和DN交互。客户端本身直接就从本地磁盘读出数据。这个性能优化被加入了CDH3u3。

如何提高hadoop中Short-Circuit Local Reads时的性能及安全性

HDFS-2246实现的short-circuit local read 是一个好的开始,但其带来了许多配置上麻烦。系统管理员必须改变DN数据目录权限,允许客户端打开相关文件。还需要定义一个白名单用户,可以使用这个特性。其他用户不允许。通常,这些用户被搞到一个特殊的UNIX 用户组里。

不幸的是,这种权限改变带来了安全漏洞。有这种权限的用户就可以直接浏览所有数据了,不仅是他们需要的数据。简直就是超级用户啊!这个在一些场景下可以接受,比如 HBase用户,但是一般来讲,它还是带来了问题。这不是一个通用的方式。

HDFS-347:让Short-Circuit Local Reads 安全

HDFS-2246的主要问题就是它将DN的所有数据路径直接开放给了客户端。其实,客户端只是想要几个其关心的数据文件。

幸亏Unix提供了可以这样做的机制,文件描述符。HDFS-347使用该机制实现安全的short-circuit local reads. 客户端向DN请求数据时,DN简单地打开blockfile和元数据文件,并直接传给客户端,而不是将路径传给客户端。因为文件描述符是只读的,客户端不能修改接收到的文件。同时不支持对block所在路径的访问,所以也就不能访问其他数据。

Windows 有类似的机制允许将文件描述符在进程间传递。CDH目前还不支持该特性,同时Windows用户可以配置dfs.cient.use.legacy.blockreader.local为true使用legacy block reader。

如何提高hadoop中Short-Circuit Local Reads时的性能及安全性

Cache 文件描述符

HDFS客户端经常多次读取相同的block文件(y尤其对HBase而言)。为了提高这种场景下的本地读,HDFS-2246实现的机制中有一个block 路径的Cache。Cache允许客户端重新打开block文件,而不需要再去访问DN。

相对于路径Cache,新机制实现了一个FileInputStreamCache,缓存文件描述符。优点在于不需要客户端重新打开数据文件。该处实现性能优于老的读取机制。

cache的大小可以通过dfs.client.read.shortcircuit.stream.cache.size调整,cache超时时间通过dfs.client.read.shortcircuit.streams.cache.expiry.ms设定。也可以关掉该cache,设置cache大小为0即可。大多数情况下,默认配置就可以了。如果你面对的是特殊的大规模的工作集和高文件描述符限制,你可以试着提高参数值。

HDFS-347配置

HDFS-347实现的新机制,所有hdfs用户都可以使用该特性,而不是局限于配置的几个用户。也没有必要去修改Unix用户组来设定谁可以访问DN路径。然而,java标准库并不包含支持文件描述符传递的库,所以该特性需要使用JNI。同时需要安装libhadoop.so库.

HDFS-347也需要一个Unix域套接字路径,可通过dfs.domain.socket.path设置。该路径必须安全地阻止无优先级进程进行中间人攻击(MITM攻击,man-in-the-middle attack)。每个套接字路径必须是root拥有或者DN用户拥有,不能使用人人都可以写或者用户组可写方式的路径。

如果你安装cloudera包 rpm,deb,cloudera会创建一个默认的安全的unix域套接字路径。同时会讲libhadoop.so安装到正确路径下。

详细配置信息可以参考 the upstream documentation

性能

新实现到底咋样呢?作者使用 hio_bench程序获取到一些性能统计数据。hiobench github 地址 https://github.com/cmccabe/hiotest。

测试案例运行在8核 intelXeon 2.13 12块磁盘服务器上,集群使用CDH4.3.1,底层使用ext4文件系统。 下图每个值是运行三次的平均值。

如何提高hadoop中Short-Circuit Local Reads时的性能及安全性

如何提高hadoop中Short-Circuit Local Reads时的性能及安全性

在所有测试案例中,HDFS-347实现是最快的,可能归功于FileInputStreamCache.相反HDFS-2246实现会重复打开ext4 块文件多次,打开文件是一个重操作。

short-circuit实现在随机读场景下比顺序读相对于hdfs初始的读取机制有相对优势。部分原因是为short-circuit local reads场景的 高速预读(readahead)还未实现。可以参考HDFS-4697参与相关讨论。

结论

SCR (short-circuit local reads)是hadoop模型下优化的一项极好的案例。他们也有如何解决规模不断增长的挑战,Cloudera目前正挑战在集群中获取每个节点更多性能方向的研究。

如果你正使用CDH4.2 或以上版本,用下新的实现把!

Colin McCabe is a Software Engineer on the Platform team, and a Hadoop Committer.