avh*_*ker 7 io performance hadoop hdfs
我是Haddoop的新手.最近我正在尝试处理(仅读取)hdfs/hadoop上的许多小文件.平均文件大小约为1 kb,文件数超过10M.由于某些限制,该程序必须用C++编写.
这只是一个性能评估,所以我只使用5台机器作为数据节点.每个数据节点都有5个数据磁盘.
我写了一个小的C++项目来直接从硬盘(而不是从HDFS)读取文件来构建性能基线.该程序将为每个磁盘创建4个读取线程.性能结果是每个磁盘大约有14MB/s.总吞吐量约为14MB/s*5*5 = 350MB/s(14MB/s*5个磁盘*5台机器).
但是,当这个程序(仍然使用C++,动态链接到libhdfs.so,创建4*5*5 = 100个线程)从hdfs集群中读取文件时,吞吐量大约只有55MB/s.
如果在mapreduce中触发此编程(hadoop流,5个作业,每个具有20个线程,总线程数仍为100),则吞吐量降至约45MB/s.(我想通过一些记账过程会减慢速度).
我想知道HDFS可以提供什么样的合理性能.如您所见,与本机代码相比,数据吞吐量仅为1/7左右.这是我配置的问题吗?还是HDFS限制?还是Java限制?什么是我的场景的最佳方式?将序列文件帮助(多)?与我们可以预期的本机IO读取相比,合理的吞吐量是多少?
这是我的一些配置:
NameNode堆大小为32G.
作业/任务节点堆大小为8G.
NameNode处理程序数:128
DataNode处理程序数:8
DataNode最大传输线程数:4096
1GBps以太网.
谢谢.
HDFS实际上不是为许多小文件设计的.
对于您阅读的每个新文件,客户端必须与namenode通信,namenode为其提供文件块的位置,然后客户端从datanode流式传输数据.
现在,在最好的情况下,客户端执行此操作一次,然后发现它是包含数据的计算机,并且可以直接从磁盘读取它.这将很快:与直接磁盘读取相当.
如果机器上没有数据,那么它必须通过网络传输数据.然后你受网络I/O速度的限制,这应该不会很糟糕,但仍然比直接磁盘读取慢一点.
但是,你会遇到更糟糕的情况 - 与namenode交谈的开销变得很大.只有1KB的文件,您就可以获得与实际数据一样多的元数据.客户端必须进行两次单独的网络交换才能从每个文件中获取数据.除此之外,namenode可能会被所有这些不同的线程所打击,因此它可能成为瓶颈.
所以要回答你的问题,是的,如果你将HDFS用于那些不能用于它的东西,它会变慢.合并您的小文件,并使用MapReduce获取数据位置,您将获得更好的性能.事实上,因为你将能够更好地利用顺序磁盘读取,所以如果从一个大的HDFS文件中读取甚至比读取许多小的本地文件更快,我也不会感到惊讶.
让我们尝试了解我们的限制,看看何时会遇到这些限制
a) 我们需要 namenode 来为我们提供文件所在位置的信息。我可以假设这个数字约为每秒数千。更多信息请参见https://issues.apache.org/jira/browse/HADOOP-2149
假设此数字为 10000K,我们应该能够获取 1K 文件的每秒 10 MB 左右的信息。(不知怎的,你会得到更多......)。b
) HDFS 的开销。这种开销主要是延迟而不是吞吐量。HDFS 可以调整为并行服务大量文件。HBase 正在这样做,我们可以从 HBase 调优指南中获取设置。这里的问题实际上是您需要多少数据节点
c) 您的 LAN。您从网络移动数据,因此可能会达到 1GB 以太网吞吐量限制。(我认为这就是你得到的。
我还必须同意 Joe 的观点 - HDFS 不是为该场景构建的,您应该使用其他技术(例如 HBase,如果您喜欢 Hadoop 堆栈)或将文件压缩在一起 - 例如压缩到序列文件中。
关于从 HDFS 读取更大的文件 - 运行 DFSIO 基准测试,这将是您的数字。
同时,单台主机上的 SSD 也可以是一个完美的解决方案。
| 归档时间: |
|
| 查看次数: |
9791 次 |
| 最近记录: |