2016-06-20 39 views
1

我是大数据世界的新手,并试图学习Hadoop。令我惊讶的是,BIG数据或Hadoop缺省情况下支持不变性,因为我们希望一次写入数据并读取多次数据,并且不变性是分布式存储和处理领域的最佳选择。同时,我读到Hadoop中实现Writable接口的所有数据类型本质上都是可变的,以支持框架中的序列化。当所有数据类型都是可变的时候,我很困惑,那么整个Hadoop将如何支持不变性?这两件事情是不是矛盾?Hadoop不可变与数据类型可变

在此先感谢您回答我的问题。

回答

1

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

1
Hadoop immutable 

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

Data type mutable 

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

//版本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相当古老,当时垃圾收集器的效率不如现在,但即使在今天,如果您要映射数十亿个对象并直接将其作为垃圾丢弃,它在运行时会产生很大的差异。

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

public class IntWritable implements WritableComparable { 
    private int value; 

    public IntWritable() {} 

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

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

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

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

在迭代的每个值是指相同的共享对象。因此,如果许多人将自己的价值观念变为正常收藏,并问自己为什么总是保持相同的价值观,那么他们会感到困惑。最后归结为性能的折衷(CPU和内存 - 想象单个密钥的数十亿个价值对象必须驻留在RAM中)与简单性之间的关系。

ref- Why should a Writable datatype be Mutable?