복붙노트

[HADOOP] Custom WritableCompare는 객체 참조를 출력으로 표시합니다

HADOOP

Custom WritableCompare는 객체 참조를 출력으로 표시합니다

나는 하둡과 자바를 처음 접했고, 내가 놓친 것이 분명하다고 느낀다. 그것이 의미가 있다면 Hadoop 1.0.3을 사용하고 있습니다.

hadoop을 사용하는 나의 목표는 많은 파일을 가져 와서 한 번에 한 파일 씩 파싱하는 것입니다 (한 줄씩). 각 파일은 여러 키-값을 생성하지만 다른 행에 대한 컨텍스트가 중요합니다. 키와 값은 다중 값 / 복합이므로 키에 대해서는 WritableCompare를 구현하고 값에 대해서는 Writable을 구현했습니다. 각 파일을 처리하는 데 약간의 CPU가 사용되므로 매퍼의 출력을 저장 한 다음 나중에 여러 리듀서를 실행하고 싶습니다.

복합 키의 경우 [http://stackoverflow.com/questions/12427090/hadoop-composite-key][1]

문제는 출력이 복합 키 및 값이 아니라 Java 객체 참조 일뿐입니다. 예: LinkKeyWritable @ bd2f9730 LinkValueWritable @ 8752408c

문제가 데이터를 전혀 줄이지 않는 것과 관련이 있는지 확실하지 않습니다.

내 주요 수업은 다음과 같습니다.

public static void main(String[] args) throws Exception {
  JobConf conf = new JobConf(Parser.class);
  conf.setJobName("raw_parser");

  conf.setOutputKeyClass(LinkKeyWritable.class);
  conf.setOutputValueClass(LinkValueWritable.class);

  conf.setMapperClass(RawMap.class);
  conf.setNumMapTasks(0);

  conf.setInputFormat(PerFileInputFormat.class);
  conf.setOutputFormat(TextOutputFormat.class);

  PerFileInputFormat.setInputPaths(conf, new Path(args[0]));
  FileOutputFormat.setOutputPath(conf, new Path(args[1]));

  JobClient.runJob(conf);
}

그리고 내 매퍼 클래스 :

공개 클래스 RawMap은 MapReduceBase 구현을 확장합니다.             매퍼 {

    public void map(NullWritable key, Text value,
            OutputCollector<LinkKeyWritable, LinkValueWritable> output,
            Reporter reporter) throws IOException {
        String json = value.toString();
        SerpyReader reader = new SerpyReader(json);
        GoogleParser parser = new GoogleParser(reader);
        for (String page : reader.getPages()) {
            String content = reader.readPageContent(page);
            parser.addPage(content);
        }
        for (Link link : parser.getLinks()) {
            LinkKeyWritable linkKey = new LinkKeyWritable(link);
            LinkValueWritable linkValue = new LinkValueWritable(link);
            output.collect(linkKey, linkValue);
        }
    }
}

Link는 기본적으로 LinkKeyWritable과 LinkValueWritable 사이에서 분리되는 다양한 정보의 구조입니다.

LinkKeyWritable :

public class LinkKeyWritable implements WritableComparable<LinkKeyWritable>{
    protected Link link;

    public LinkKeyWritable() {
        super();
        link = new Link();
    }

    public LinkKeyWritable(Link link) {
        super();
        this.link = link;
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        link.batchDay = in.readLong();
        link.source = in.readUTF();
        link.domain = in.readUTF();
        link.path = in.readUTF();
    }

    @Override
    public void write(DataOutput out) throws IOException {
        out.writeLong(link.batchDay);
        out.writeUTF(link.source);
        out.writeUTF(link.domain);
        out.writeUTF(link.path);
    }

    @Override
    public int compareTo(LinkKeyWritable o) {
        return ComparisonChain.start().
                compare(link.batchDay, o.link.batchDay).
                compare(link.domain, o.link.domain).
                compare(link.path, o.link.path).
                result();
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(link.batchDay, link.source, link.domain, link.path);
    }

    @Override
    public boolean equals(final Object obj){
        if(obj instanceof LinkKeyWritable) {
            final LinkKeyWritable o = (LinkKeyWritable)obj;
            return Objects.equal(link.batchDay, o.link.batchDay)
                    && Objects.equal(link.source, o.link.source)
                    && Objects.equal(link.domain, o.link.domain)
                    && Objects.equal(link.path, o.link.path);
        }
        return false;
    }
}

연결 가능한 값 :

public class LinkValueWritable implements Writable{
    protected Link link;

    public LinkValueWritable() {
        link = new Link();
    }

    public LinkValueWritable(Link link) {
        this.link = new Link();
        this.link.type = link.type;
        this.link.description = link.description;
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        link.type = in.readUTF();
        link.description = in.readUTF();
    }

    @Override
    public void write(DataOutput out) throws IOException {
        out.writeUTF(link.type);
        out.writeUTF(link.description);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(link.type, link.description);
    }

    @Override
    public boolean equals(final Object obj){
        if(obj instanceof LinkKeyWritable) {
            final LinkKeyWritable o = (LinkKeyWritable)obj;
            return Objects.equal(link.type, o.link.type)
                    && Objects.equal(link.description, o.link.description);
        }
        return false;
    }
}

해결법

  1. ==============================

    1.대답은 TextOutputFormat 구현에 있다고 생각합니다. 특히 LineRecordWriter의 writeObject 메소드는 다음과 같습니다.

    대답은 TextOutputFormat 구현에 있다고 생각합니다. 특히 LineRecordWriter의 writeObject 메소드는 다음과 같습니다.

    /**
     * Write the object to the byte stream, handling Text as a special
     * case.
     * @param o the object to print
     * @throws IOException if the write throws, we pass it on
     */
    private void writeObject(Object o) throws IOException {
      if (o instanceof Text) {
        Text to = (Text) o;
        out.write(to.getBytes(), 0, to.getLength());
      } else {
        out.write(o.toString().getBytes(utf8));
      }
    }
    

    보시다시피, 키 또는 값이 Text 객체가 아닌 경우 키 또는 값이 toString 메소드를 호출하여 기록합니다. 키와 값에서 toString을 구현하지 않은 상태로 두었으므로 Object 클래스의 구현을 사용하고 있으며 이는 참조를 작성합니다.

    적절한 toString 함수를 작성하거나 다른 OutputFormat을 사용해야한다고 말하고 싶습니다.

  2. ==============================

    2.원하는대로 객체 목록이있는 것 같습니다. 못생긴 Java 참조 대신 사람이 읽을 수있는 버전을 인쇄하려면 쓰기 가능 항목에 toString ()을 구현해야합니다.

    원하는대로 객체 목록이있는 것 같습니다. 못생긴 Java 참조 대신 사람이 읽을 수있는 버전을 인쇄하려면 쓰기 가능 항목에 toString ()을 구현해야합니다.

  3. from https://stackoverflow.com/questions/12937581/custom-writablecompare-displays-object-reference-as-output by cc-by-sa and MIT license