为什么可写数据类型应该是可变的?在map、combine、shuffle或reduce进程中使用text(vs string)作为key/value的数据类型有什么好处?谢谢和问候,拉贾
iszxjhcz1#
简单地说,原因 Writable 不能是 Immutable 是 readFields(DataInput) 中的方法 Writable . 就像 Hadoop 反序列化中的示例,以使用默认(无参数)构造函数和调用 readFields 解析值。因为在构造中没有赋值,所以对象必须是可变的。
Writable
Immutable
readFields(DataInput)
Hadoop
readFields
elcex8rz2#
您不能选择,这些数据类型必须是可变的。原因是序列化机制。让我们看看代码:
// version 1.x MapRunner#run() K1 key = input.createKey(); V1 value = input.createValue(); while (input.next(key, value)) { // map pair to output mapper.map(key, value, output, reporter); ...
所以我们重新使用同一个键/值对示例。为什么?我不知道当时的设计决策,但我认为这是为了减少垃圾对象的数量。请注意,hadoop非常古老,那时的垃圾收集器没有今天的效率高,但是即使在今天,如果您Map数十亿个对象并将它们作为垃圾直接丢弃,在运行时也会有很大的不同。你为什么不能 Writable 真正不可变的类型是不能将字段声明为 final . 让我们用 IntWritable :
final
IntWritable
public class IntWritable implements WritableComparable { private int value; public IntWritable() {} public IntWritable(int value) { set(value); } ...
如果您使它不可变,它肯定不会再与序列化过程一起工作,因为您需要定义 value 最后。这是行不通的,因为键和值是在运行时通过反射示例化的。这需要一个默认构造函数,因此 InputFormat 无法猜测填充最终数据字段所需的参数。因此,重用示例的整个概念显然与不变性的概念相矛盾。但是,您应该问问自己,在map/reduce中,一个不可变的键/值应该有什么好处。在JoshuaBloch的高效java第15条中,他指出不可变类更易于设计、实现和使用。他是对的,因为hadoop的reducer是最糟糕的可变性示例:
value
InputFormat
void reduce(IntWritable key, Iterable<Text> values, Context context) ...
iterable中的每个值都引用 same 共享对象。因此,如果他们将自己的值缓冲到一个正常的集合中,并自问为什么它总是保留相同的值,许多人就会感到困惑。最后,它归结为性能(cpu和内存——想象一下一个键的数十亿个值对象必须驻留在ram中)与简单性之间的权衡。
same
2条答案
按热度按时间iszxjhcz1#
简单地说,原因
Writable
不能是Immutable
是readFields(DataInput)
中的方法Writable
. 就像Hadoop
反序列化中的示例,以使用默认(无参数)构造函数和调用readFields
解析值。因为在构造中没有赋值,所以对象必须是可变的。elcex8rz2#
您不能选择,这些数据类型必须是可变的。
原因是序列化机制。让我们看看代码:
所以我们重新使用同一个键/值对示例。为什么?我不知道当时的设计决策,但我认为这是为了减少垃圾对象的数量。请注意,hadoop非常古老,那时的垃圾收集器没有今天的效率高,但是即使在今天,如果您Map数十亿个对象并将它们作为垃圾直接丢弃,在运行时也会有很大的不同。
你为什么不能
Writable
真正不可变的类型是不能将字段声明为final
. 让我们用IntWritable
:如果您使它不可变,它肯定不会再与序列化过程一起工作,因为您需要定义
value
最后。这是行不通的,因为键和值是在运行时通过反射示例化的。这需要一个默认构造函数,因此InputFormat
无法猜测填充最终数据字段所需的参数。因此,重用示例的整个概念显然与不变性的概念相矛盾。但是,您应该问问自己,在map/reduce中,一个不可变的键/值应该有什么好处。在JoshuaBloch的高效java第15条中,他指出不可变类更易于设计、实现和使用。他是对的,因为hadoop的reducer是最糟糕的可变性示例:
iterable中的每个值都引用
same
共享对象。因此,如果他们将自己的值缓冲到一个正常的集合中,并自问为什么它总是保留相同的值,许多人就会感到困惑。最后,它归结为性能(cpu和内存——想象一下一个键的数十亿个值对象必须驻留在ram中)与简单性之间的权衡。