복붙노트

[HADOOP] hadoop의 hdfs에 JSON 데이터 저장

HADOOP

hadoop의 hdfs에 JSON 데이터 저장

다음 리듀서 클래스가 있습니다

public static class TokenCounterReducer extends Reducer<Text, Text, Text, Text> {
    public void reduce(Text key, Iterable<Text> values, Context context)
            throws IOException, InterruptedException {

        JSONObject jsn = new JSONObject();

        for (Text value : values) {
            String[] vals = value.toString().split("\t");
            String[] targetNodes = vals[0].toString().split(",",-1);
            jsn.put("source",vals[1] );
            jsn.put("target",targetNodes);

        }
        // context.write(key, new Text(sum));
    }
}

예제를 통해 (면책 조항 : 초보자) 일반적인 출력 유형이 키 / 값 저장소와 같은 것으로 보입니다.

그러나 출력에 키가 없으면 어떻게해야합니까? 또는 출력이 다른 형식 (필자의 경우 json) 인 경우 어떻게해야합니까?

어쨌든 위 코드에서 : json 객체를 HDFS에 쓰려고합니까?

하둡 스트리밍에서 아주 사소한 것이었지만 하둡 자바에서 어떻게해야합니까?

해결법

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

    1.키 / 값의 개념에 신경 쓰지 않고 JSON 객체 목록을 HDFS에 쓰려면 Reducer 출력 값에 NullWritable을 사용하면됩니다.

    키 / 값의 개념에 신경 쓰지 않고 JSON 객체 목록을 HDFS에 쓰려면 Reducer 출력 값에 NullWritable을 사용하면됩니다.

    public static class TokenCounterReducer extends Reducer<Text, Text, Text, NullWritable> {
        public void reduce(Text key, Iterable<Text> values, Context context)
                throws IOException, InterruptedException {
            for (Text value : values) {
                JSONObject jsn = new JSONObject();
                ....
                context.write(new Text(jsn.toString()), null);
            }
        }
    }
    

    다음과 같이 작업 구성을 변경해야합니다.

    job.setOutputValueClass(NullWritable.class);
    

    JSON 객체를 HDFS에 작성함으로써 위에서 설명한 JSON의 문자열 표현을 저장하고 싶다는 것을 이해했습니다. JSON의 이진 표현을 HDFS에 저장하려면 SequenceFile을 사용해야합니다. 분명히 당신은 이것을 위해 자신의 Writable을 작성할 수 있지만 간단한 String 표현을 원한다면 이것처럼 더 쉽다고 생각합니다.

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

    2.Hadoop의 OutputFormat 인터페이스를 사용하여 원하는대로 데이터를 쓰는 사용자 정의 형식을 만들 수 있습니다. 예를 들어 JSON 객체로 데이터를 작성해야하는 경우 다음을 수행 할 수 있습니다.

    Hadoop의 OutputFormat 인터페이스를 사용하여 원하는대로 데이터를 쓰는 사용자 정의 형식을 만들 수 있습니다. 예를 들어 JSON 객체로 데이터를 작성해야하는 경우 다음을 수행 할 수 있습니다.

    public class JsonOutputFormat extends TextOutputFormat<Text, IntWritable> {
        @Override
        public RecordWriter<Text, IntWritable> getRecordWriter(
                TaskAttemptContext context) throws IOException, 
                      InterruptedException {
            Configuration conf = context.getConfiguration();
            Path path = getOutputPath(context);
            FileSystem fs = path.getFileSystem(conf);
            FSDataOutputStream out = 
                    fs.create(new Path(path,context.getJobName()));
            return new JsonRecordWriter(out);
        }
    
        private static class JsonRecordWriter extends 
              LineRecordWriter<Text,IntWritable>{
            boolean firstRecord = true;
            @Override
            public synchronized void close(TaskAttemptContext context)
                    throws IOException {
                out.writeChar('{');
                super.close(null);
            }
    
            @Override
            public synchronized void write(Text key, IntWritable value)
                    throws IOException {
                if (!firstRecord){
                    out.writeChars(",\r\n");
                    firstRecord = false;
                }
                out.writeChars("\"" + key.toString() + "\":\""+
                        value.toString()+"\"");
            }
    
            public JsonRecordWriter(DataOutputStream out) 
                    throws IOException{
                super(out);
                out.writeChar('}');
            }
        }
    }
    

    그리고 출력에 키를 원하지 않으면 다음과 같이 null을 방출하십시오.

    context.write(NullWritable.get(), new IntWritable(sum));
    

    HTH

  3. from https://stackoverflow.com/questions/16925133/saving-json-data-in-hdfs-in-hadoop by cc-by-sa and MIT license