考虑跑步 Hadoop
作业,其中自定义inputformat需要将几个简单的值从其重写的内部传递给驱动程序类(即,传递给启动作业的类) getSplits()
方法,使用新的 mapreduce
api(与 mapred
).
理想情况下,这些值应该返回到内存中(而不是保存到 HDFS
或是去医院 DistributedCache
).
如果这些值只是数字,人们可能会尝试使用 Hadoop
计数器。然而,在许多测试中,计数器似乎不可用 getSplits()
不管怎样,它们只限于数字。
另一种方法是使用 Configuration
作业的对象,如源代码所示,对于两个 getSplits()
还有司机班。
在这种情况下,如果 InputFormat
如果要向driver类“返回”一个(比如)正的long值,则代码如下所示:
// In the custom InputFormat.
public List<InputSplit> getSplits(JobContext job) throws IOException
{
...
long value = ... // A value >= 0
job.getConfiguration().setLong("value", value);
...
}
// In the Hadoop driver class.
Job job = ... // Get the job to be launched
...
job.submit(); // Start running the job
...
while (!job.isComplete())
{
...
if (job.getConfiguration().getLong("value", -1))
{
...
}
else
{
continue; // Wait for the value to be set by getSplits()
}
...
}
上述方法在测试中有效,但这是一种“安全”的价值观交流方式吗?
还是有更好的方法来处理这种内存中的“回调”?
更新
“内存回调”技术可能根本不起作用 Hadoop
因此,如上所述,更安全的方法是,不保存要在 Configuration
对象,创建一个自定义对象,将其序列化(例如,作为json),保存它(在hdfs或分布式缓存中),并在driver类中读取它。我也测试了这种方法,它的工作原理和预期一样。
1条答案
按热度按时间mw3dktmi1#
使用配置是一个非常合适的解决方案(当然,对于一个我不确定我是否理解的问题),但是一旦作业被提交给了job tracker,您将无法修改此值(客户端或任务端)并期望在命令的另一侧看到更改(例如,在Map任务中设置配置值将不会持久化到其他Map器,也不会持久化到还原器,也不会对作业跟踪器可见)。
因此,在您的示例中,将getsplits中的信息传递回客户机轮询循环(以查看作业何时实际完成了输入拆分的定义)是很好的。
你使用这个的最大目的或用例是什么?