【问题标题】:saving json data in hdfs in hadoop在hadoop的hdfs中保存json数据
【发布时间】:2013-05-31 06:43:06
【问题描述】:

我有以下 Reducer 类

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?

这在 Hadoop 流中非常微不足道。但我如何在 Hadoop java 中做到这一点?

【问题讨论】:

    标签: java json hadoop mapreduce reducers


    【解决方案1】:

    如果您只想将 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,但我觉得如果您打算使用简单的字符串表示形式,这样会更容易。

    【讨论】:

    • 嗨@Charles 我是Hadoop的新手,一旦我们将json数据文件存储在hdfs中,如果我们不应用任何键值概念,我们如何检索数据。
    【解决方案2】:

    您可以使用 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

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 2020-02-21
      • 2023-03-25
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      相关资源
      最近更新 更多