Hadoop不可变与数据类型可变

时间:2016-06-20 03:30:45

标签: hadoop

我是Big Data世界的新手,并试图学习Hadoop。让我感到惊讶的是,BIG数据或Hadoop默认支持不变性,因为我们想要一次编写数据并多次读取,而且不变性是分布式存储和处理领域的最佳选择。与此同时,我读到Hadoop中实现Writable接口的所有数据类型本质上都是可变的,以支持框架中的序列化。当所有数据类型都是可变的时,我感到很困惑,那么Hadoop整体上将支持不变性?两件事情都不矛盾吗?

提前感谢您回答我的问题。

2 个答案:

答案 0 :(得分:2)

Hadoop immutable

使用Hadoop,所有写入的记录都是不可变的,因为Hadoop不支持随机写入。有时这可能是一种真正的痛苦,但它的扩展性非常好。您甚至会发现越来越多的语言正在带回这种不可变对象的概念。为什么?好吧,因为可变对象存在一些问题。首先,可变对象必须处理并发。仅此一项需要额外的编程,以确保一次只能由一个源更新对象。更新已写入磁盘的可变对象时,需要在更改下方重写整个文件。这可能代价高昂。 REF - https://streever.atlassian.net/wiki/display/HADOOP/2014/03/06/Managing+Mutable+Data+in+an+Immutable+Big+Data+World

Data type mutable

原因是序列化机制。我们来看看代码:

// version 1.x MapRunner#run() K1 key = input.createKey(); V1值= input.createValue();

while (input.next(key, value)) {
   // map pair to output
   mapper.map(key, value, output, reporter);

... 所以我们重新使用相同的键/值对实例。为什么?我当时并不知道设计决策,但我认为这是为了减少垃圾对象的数量。请注意,Hadoop已经很老了,当时垃圾收集器的效率还不如今天那么高,但即使在今天,如果要绘制数十亿个对象并直接将它们作为垃圾丢弃,它在运行时也会产生很大的不同。

您不能使Writable类型真正不可变的真正原因是您不能将字段声明为final。让我们用IntWritable做一个简单的例子:

public class IntWritable implements WritableComparable {
  private int value;

  public IntWritable() {}

  public IntWritable(int value) { set(value); }

... 如果你将它变为不可变,它肯定不再适用于序列化过程,因为你需要定义值final。这不起作用,因为键和值是在运行时通过反射实例化的。这需要一个默认构造函数,因此InputFormat无法猜测填充最终数据字段所需的参数。因此,重用实例的整个概念显然与不变性的概念相矛盾。

但是,您应该问自己,Map / Reduce中不可变键/值应该具有什么样的好处。在Joshua Bloch的“有效Java”第15项中,他指出不可变类更容易设计,实现和使用。而他是对的,因为Hadoop的减速器是可变性最糟糕的例子:

void reduce(IntWritable key, Iterable<Text> values, Context context) ...

iterable中的每个值都指向同一个共享对象。因此,如果他们将他们的价值缓冲到正常的集合中并且问自己为什么它总是保留相同的价值,那么很多人会感到困惑。

最后,归结为性能的折衷(cpu和内存 - 想象一个密钥的数十亿个值对象必须驻留在RAM中)与简单性相比。

REF- Why should a Writable datatype be Mutable?

答案 1 :(得分:1)

我认为你可能会混淆HDFS,即存储文件,这些文件通常只写一次并且不支持使用内存中对象(Writables)进行任意覆盖。这些可以编辑,因为它们没有提交到磁盘,并且为每个操作创建一个新的Writeable会很昂贵(想想GC成本)。