如果我们可以在Hadoop中更改数据块大小,请告诉我如何操作。 更改块大小是否有利,如果是,那么让我知道为什么以及如何?如果没有,那么让我知道为什么以及如何?
答案 0 :(得分:2)
这个话题似乎有很多混乱,也有错误的建议。为了解除混乱,有必要考虑HDFS的实际实施方式:
HDFS是基于分布式磁盘的文件系统的抽象。所以"阻止"和" blocksize"具有与通常理解的不同的含义。对于HDFS a"文件"只是一个块的集合,每个块"块"作为回报,将其存储为datanode上的实际文件。事实上,根据复制因素,同一文件存储在多个数据节点上。这些单个文件的块大小及其他性能特征依赖于各个数据节点的底层文件系统。
维护HDFS文件与数据节点上的各个文件之间的映射
由namenode。但是namenode并不期望特定的块大小,它只是存储
在创建HDFS文件期间创建的映射,通常是拆分的
根据默认dfs.blocksize
(但可以单独覆盖)。
这意味着,例如,如果您有1 MB的文件,其复制数为3,块大小为64 MB,你不会丢失63 MB * 3 = 189 MB,因为实际上只存储了3个1 MB的文件 使用底层文件系统的标准块大小(例如ext4)。
所以问题变成了一个好的dfs.blocksize
,以及是否可以改变它。
让我首先列出更大块大小的方面:
更大的默认拆分:即使可以在作业级别配置splitsize,大多数人都不会考虑这一点,只是采用默认值,通常是块大小。如果你的splitsize太小了,你可能会得到太多的地图制作者没有太多的工作要做,这反过来会导致更小的输出文件,不必要的开销和许多占用的容器,这可能会使其他工作挨饿。这也会对reduce阶段产生负面影响,因为必须从所有映射器中获取结果。
当然,理想的分裂很大程度上取决于你要做的工作。但是你总是可以在必要时设置一个较低的splitsize,而当你设置一个比blocksize更高的splitsize你可能会丢失一些数据局部性。
后一方面的问题比人们想象的要少,因为HDFS中的块放置规则是:第一个块写在创建文件的进程运行的datanode上,第二个块写在另一个节点上同一个机架和另一个机架上的节点上的第三个机架。因此,通常可以在单个数据节点上找到文件的每个块的一个副本,因此即使当一个映射器由于分块大小而读取多个块时仍然可以实现数据局部性,这是块大小的倍数。仍然在这种情况下,mapred框架只能选择一个节点而不是通常的三个节点来实现数据局部性,因此效果不能被拒绝。
但最终这个更大的块大小的点可能是最弱的,因为必要时可以独立设置splitsize。
但是对于较小的块大小也必须有参数,否则我们应该将它设置为无穷大......
将这些因素相互加权取决于您的数据类型,群集,工作负载等。但总的来说,我认为默认的块大小128 MB对于典型的用例来说已经有点低了。 512 MB甚至1 GB可能值得考虑。
但在你深入研究之前,首先要检查输入文件的大小。如果您的大多数文件很小并且甚至达不到最大默认值块大小,那么您的blocksize基本上总是文件大小,并且它不会帮助增加默认的块大小。有一些解决方法,例如使用输入组合器来避免产生过多的映射器,但最终你需要确保输入文件足够大以利用大块。
如果您的文件已经很小,请不要通过使块大小更小来解决问题。
答案 1 :(得分:1)
这取决于输入数据。映射器的数量与输入分割成正比,这取决于DFS块大小。
如果要最大化非常大的输入文件的吞吐量,最好使用非常大的块(128MB甚至256MB)。
如果作业的输入超过1TB,请考虑将输入数据集的块大小增加到256M甚至512M,以便任务数量更小。
对于较小的文件,使用较小的块大小更好。
看看这个article
如果您有小文件且小于最小DFS块大小,则可以使用一些替代方法,如HAR或SequenceFiles。
查看此cloudera博客
答案 2 :(得分:1)
除非在{hdfs-site.xml中将dfs.blocksize
参数定义为final,否则您可以随时更改块大小。
更改块大小
hadoop fs
命令时,您可以运行hadoop fs -Ddfs.blocksize=67108864 -put <local_file> <hdfs_path>
。此命令将保存64MB块大小的文件hadoop jar
命令 - hadoop jar <jar_file> <class> -Ddfs.blocksize=<desired_block_size> <other_args>
时。 Reducer将使用定义的块大小,同时将输出存储在HDFS中更改块大小的标准:
我已经在这个performance tuning播放列表中的2和3中涵盖了大部分内容。