这是一个涉及Hadoop / HDFS的概念性问题。假设您有一个包含10亿行的文件。并且为了简单起见,我们考虑每行的格式为<k,v>
,其中k是从开头开始的行的偏移量,value是行的内容。
现在,当我们说要运行N个映射任务时,框架是否会将输入文件拆分为N个拆分并在该拆分上运行每个映射任务?或者我们是否必须编写一个分区函数来执行N分割并在生成的分割上运行每个映射任务?
我想知道的是,拆分是在内部完成还是我们必须手动拆分数据?
更具体地说,每次调用map()函数时,它的Key key and Value val
参数是什么?
谢谢, 迪帕克
答案 0 :(得分:23)
InputFormat
负责提供分组。
通常,如果您有n个节点,HDFS将在所有这n个节点上分发文件。如果你开始一个工作,默认情况下会有n个映射器。感谢Hadoop,计算机上的映射器将处理存储在此节点上的部分数据。我认为这叫做Rack awareness
。
总而言之:在HDFS中上传数据并启动MR作业。 Hadoop将关注优化执行。
答案 1 :(得分:14)
将文件拆分为HDFS块并复制块。 Hadoop根据数据位置原则为拆分分配节点。 Hadoop将尝试在块所在的节点上执行映射器。由于复制,有多个这样的节点托管相同的块。
如果节点不可用,Hadoop将尝试选择最接近托管数据块的节点的节点。例如,它可以在同一个机架中选择另一个节点。由于各种原因,节点可能不可用;所有地图位置都可能正在使用中,或者节点可能只是关闭。
答案 2 :(得分:8)
幸运的是,一切都将由框架照顾。
MapReduce 数据处理由输入拆分的概念驱动。为特定应用程序计算的输入拆分数决定了映射器任务的数量。
映射数通常由输入文件中的DFS块数驱动。
在可能的情况下,将每个映射器任务分配给存储输入分割的从属节点。资源管理器(或JobTracker,如果您在Hadoop 1中)尽力确保在本地处理输入拆分。
如果由于跨越数据节点边界的输入拆分而无法实现 数据位置 ,则某些数据将从一个数据节点传输到另一个数据节点。 / p>
假设有128 MB的块,最后一条记录不适合阻止a 并在 Block b 中传播,那么 Block b 将被复制到具有阻止
的节点看一下这个图。
查看相关问题
About Hadoop/HDFS file splitting
How does Hadoop process records split across block boundaries?
答案 3 :(得分:6)
为了更好地理解InputSplits如何在hadoop中工作,我建议阅读article written by hadoop for dummies。这真的很有帮助。
答案 4 :(得分:4)
我认为Deepak所询问的更多是关于如何确定地图功能的每个调用的输入,而不是每个地图节点上的数据。我根据问题的第二部分说这个: 更具体地说,每次调用map()函数时,它的Key键和Value val参数是什么?
实际上,同样的问题让我来到这里,如果我是一位经验丰富的hadoop开发者,我可能会将其解释为上面的答案。
要回答这个问题,
根据我们为 InputFormat 设置的值,拆分给定地图节点上的文件。 (这是使用setInputFormat()在java中完成的!)
一个例子:
conf.setInputFormat(TextInputFormat.class); 这里,通过将TextInputFormat传递给setInputFormat函数,我们告诉hadoop将地图节点处输入文件的每个行视为map函数的输入。换行或回车用于发出线路终点信号。 更多信息,请访问TextInputFormat!
在这个例子中: 键是文件中的位置,值是文本行。
希望这有帮助。
答案 5 :(得分:1)
FileInputFormat 是一个抽象类,它定义了如何读取和溢出输入文件。 FileInputFormat提供以下功能: 1.选择应该用作输入的文件/对象 2.定义将文件分解为任务的inputsplits。
根据hadoopp的基本功能,如果有n个分裂则会有n个映射器。
答案 6 :(得分:1)
运行Hadoop作业时,它会将输入文件拆分为块,并将每个拆分分配给映射器进行处理;这叫做InputSplit。
答案 7 :(得分:1)
块大小与输入分割大小之间的差异。
输入拆分是数据的逻辑拆分,主要用于MapReduce程序或其他处理技术中的数据处理。输入拆分大小是用户定义的值,Hadoop Developer可以根据数据大小选择拆分大小(您正在处理多少数据)。
Input Split主要用于控制MapReduce程序中Mapper的数量。如果您尚未在MapReduce程序中定义输入分割大小,则在数据处理期间,默认HDFS块分割将被视为输入分割。
示例:强>
假设您有一个100MB的文件,HDFS默认块配置为64MB,那么它将被分成2个分割并占用两个HDFS块。现在您有一个MapReduce程序来处理这些数据,但是您没有指定输入拆分,那么基于块数(2块)将被视为MapReduce处理的输入拆分,并且将为此作业分配两个映射器。但是假设您已经在MapReduce程序中指定了分割大小(比如100MB),那么两个块(2个块)将被视为MapReduce处理的单个分割,并且将为此作业分配一个Mapper。
现在假设您已经在MapReduce程序中指定了分割大小(比方说25MB),那么MapReduce程序将有4个输入分割,并且将为该作业分配4个Mapper。
<强>结论:强>
来源:https://hadoopjournal.wordpress.com/2015/06/30/mapreduce-input-split-versus-hdfs-blocks/
答案 8 :(得分:0)
简短的回答是InputFormat负责文件的拆分。
我处理这个问题的方法是查看它的默认TextInputFormat类:
所有InputFormat类都是FileInputFormat的子类,它负责拆分。
具体来说,FileInputFormat的getSplit函数从JobContext中定义的文件列表生成一个InputSplit列表。拆分基于字节大小,其Min和Max可以在项目xml文件中任意定义。
答案 9 :(得分:0)
有一个单独的地图缩小作业,将文件拆分为块。对大文件使用FileInputFormat,对较小文件使用CombineFileInput格式。您还可以通过issplittable方法检查输入是否可以拆分为块。然后将每个块馈送到数据节点,在该数据节点处运行映射减少作业以进行进一步分析。块的大小取决于您在mapred.max.split.size参数中提到的大小。
答案 10 :(得分:0)
FileInputFormat.addInputPath(job,new Path(args [0]));或
conf.setInputFormat(TextInputFormat.class);
类 FileInputFormat funcation addInputPath , setInputFormat 负责inputsplit,此代码也定义了创建的映射器数量。我们可以说inputsplit和映射器的数量与用于在HDFS上存储输入文件的块数成正比。
实施例。如果我们有大小为74 Mb的输入文件,则该文件以两个块(64 MB和10 Mb)存储在HDFS上。所以这个文件的inputsplit是两个,并且创建了两个映射器实例来读取这个输入文件。