hadoop 实现通用列表可写

标签 hadoop

我正在构建一个 map reduce 作业流水线(将一个 MR 作业的输出作为输入提供给另一个)。传递的值相当复杂,因为存在不同类型的列表和以列表形式显示值的 HashMap 。 Hadoop api 似乎没有 ListWritable。我正在尝试编写一个泛型,但似乎我无法在我的 readFields 实现中实例化一个泛型类型,除非我传入类类型本身:

public class ListWritable<T extends Writable> implements Writable {
    private List<T> list;
    private Class<T> clazz;

    public ListWritable(Class<T> clazz) {
       this.clazz = clazz;
       list = new ArrayList<T>();
    }

    @Override
    public void write(DataOutput out) throws IOException {
        out.writeInt(list.size());
        for (T element : list) {
            element.write(out);
        }
     }

     @Override
     public void readFields(DataInput in) throws IOException{
     int count = in.readInt();
     this.list = new ArrayList<T>();
     for (int i = 0; i < count; i++) {
        try {
            T obj = clazz.newInstance();
            obj.readFields(in);
            list.add(obj);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
      }
    }
}

但是 hadoop 要求所有可写对象都有一个无参数构造函数来读回值。 有没有人试图做同样的事情并解决了这个问题? TIA。

最佳答案

我有一个像这个这样的可写对象的扩展库,除了我总是将类型声明为自界通用类型的抽象类,并且当我使用它时,我声明了一个简单的子类,所有类型都具体化了。 Hadoop 是如此可怕地基于反射,以至于在实际工作中不使用泛型几乎总是更好;然而,泛型作为作业 I/O 类型的父类(super class)型可能非常有用。

例如

public abstract class AbstractListWritable< T extends Writable & Cloneable, U extends AbstractListWritable< T, U > >
implements Writable {
    T tCursor;
    List< T > ltBacking;
    protected AbstractListWritable( T tCursor ) {
        this.tCursor = tCursor.clone();
        this.ltBacking = new ArrayList< T >();
    }
    ...
    @Override
    public void readFields(DataInput in) throws IOException {
        int count = in.readInt();
        this.ltBacking.clear();
        for (int i = 0; i < count; i++) {
            tCursor.readFields(in);
            list.add(tCursor.clone());
        }
    }
}

public class TextListWritable extends AbstractListWritable< Text, TextListWritable > {
    public TextListWritable() {
        super( new Text() );
    }
}

Thomas 的回答将允许异构 列表,除了因为通用类型会阻止您创建一个列表,而且 I/O 几乎总是 Hadoop 中的瓶颈,我不推荐该策略.

关于hadoop 实现通用列表可写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11306650/

相关文章:

csv - 如何为 “big data”分析项目设置架构?

azure - Azure 上的 Hadoop,我可以使用不同的 Blob 存储容器进行 I/O 吗?

hadoop - 具有Sqoop导入的动态分区

hadoop - CDH 4.1 : Error running child : java. lang.OutOfMemoryError:Java堆空间

hadoop - 将防火墙日志字段加载到 Hive 表

java - org.apache.thrift.TApplicationException:必填字段 'client_protocol'未设置

hadoop - 如何在map中检索指标并在集群中的每台机器上进行精简?

hadoop - 在 HIVE 中执行 INSERT INTO SELECT 语句时会创建空零件文件

hadoop - 一项 hadoop MR 作业的多个 HDFS 源

postgresql - 如何将增量数据从PostgresQL加载到HDFS?