我的问题是,我如何制作计数器,以便在其中放入诸如doubles之类的东西(是的,我确实使用了LongValue,但这给了我0)?
long
值。MapReduce作业实现可以通过TaskAttemptContext
获得对Counter
的句柄。
http://hadoop.apache.org/docs/r2.7.1/api/org/apache/hadoop/mapreduce/TaskAttemptContext.html#getCounter(java.lang.Enum)
在获得Counter
的句柄后,作业可以将计数器增加一个增量,也可以将其设置为特定值。
http://hadoop.apache.org/docs/r2.7.1/api/org/apache/hadoop/mapreduce/Counter.html#increment(长)
http://hadoop.apache.org/docs/r2.7.1/api/org/apache/hadoop/mapreduce/Counter.html#setValue(长)
请注意,方法签名都是根据long
指定的。域模型不支持使用double
或任何其他数据类型作为计数器值。
如果这是绝对必要的,那么您可以想出一些创造性的方法将数据类型编码为long
。这样做的一种方式是利用long
和double
都是64位宽的事实。然后可以使用Double#doubleToLongBits
将double
值编码为long
。
http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#doubleToLongBits(双)
然而,以后理解这一点的唯一方法是编写自定义代码,在作业完成后打开计数器值的包装并将其传递给Double#longBitsToDouble
。
http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#longBitsToDouble(长)
不过,这将是Hadoop MapReduce作业计数器的一种非常不寻常的用法。
作为一种变通方法,您可以执行类似的操作
long convert = (long) (mydoubleVal * 10000);
context.getCounter(MyCounter.name1).setValue(convert);
在Driver中,您可以获得双倍值。
long c2 = job0.getCounters().findCounter(MyCounter.name1)
.getValue();
double getMyVal= (double) c2 / 10000;