在Hadoop中使用NullWritable的优点
与使用null
文本(即new Text(null)
)相比,将NullWritable
用于null
键/值有什么好处。 我从“Hadoop:The Definitive Guide”一书中看到以下内容。
NullWritable
是一种特殊类型的Writable
,因为它具有零长度序列化。 没有字节写入或读取流。 它用作占位符; 例如,在MapReduce中,当您不需要使用该位置时,可以将键或值声明为NullWritable
– 它有效地存储常量空值。 当您想要存储值列表而不是键值对时,NullWritable也可以用作SequenceFile
中的键。 它是一个不可变的单例:可以通过调用NullWritable.get()
来检索实例
我不清楚如何使用NullWritable
写出输出? 在开始输出文件中是否会有一个常量值,表明此文件的键或值为null
,以便MapReduce框架可以忽略读取null
键/值(以null
为准)? 另外,实际上如何序列化null
文本?
谢谢,
Venkat
键/值类型必须在运行时给出,因此编写或读取NullWritables
任何内容NullWritables
将提前知道它将处理该类型; 文件中没有标记或任何内容。 从技术上讲, NullWritables
是“读取”的,只是“读取” NullWritable
实际上是一个无操作。 你可以亲眼看到没有任何书面或阅读:
NullWritable nw = NullWritable.get(); ByteArrayOutputStream out = new ByteArrayOutputStream(); nw.write(new DataOutputStream(out)); System.out.println(Arrays.toString(out.toByteArray())); // prints "[]" ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]); nw.readFields(new DataInputStream(in)); // works just fine
至于你关于new Text(null)
问题,你可以尝试一下:
Text text = new Text((String)null); ByteArrayOutputStream out = new ByteArrayOutputStream(); text.write(new DataOutputStream(out)); // throws NullPointerException System.out.println(Arrays.toString(out.toByteArray()));
Text
将无法使用null
String
。
我改变了run方法。 并取得成功
@Override public int run(String[] strings) throws Exception { Configuration config = HBaseConfiguration.create(); //set job name Job job = new Job(config, "Import from file "); job.setJarByClass(LogRun.class); //set map class job.setMapperClass(LogMapper.class); //set output format and output table name //job.setOutputFormatClass(TableOutputFormat.class); //job.getConfiguration().set(TableOutputFormat.OUTPUT_TABLE, "crm_data"); //job.setOutputKeyClass(ImmutableBytesWritable.class); //job.setOutputValueClass(Put.class); TableMapReduceUtil.initTableReducerJob("crm_data", null, job); job.setNumReduceTasks(0); TableMapReduceUtil.addDependencyJars(job); FileInputFormat.addInputPath(job, new Path(strings[0])); int ret = job.waitForCompletion(true) ? 0 : 1; return ret; }
你总是可以将你的字符串包装在你自己的Writable类中,并且有一个布尔表示它有空字符串:
@Override public void readFields(DataInput in) throws IOException { ... boolean hasWord = in.readBoolean(); if( hasWord ) { word = in.readUTF(); } ... }
和
@Override public void write(DataOutput out) throws IOException { ... boolean hasWord = StringUtils.isNotBlank(word); out.writeBoolean(hasWord); if(hasWord) { out.writeUTF(word); } ... }
- Hadoop maven依赖性错误 – 找不到hadoop类
- 无法validationserde:org.openx.data.jsonserde.jsonserde
- 错误的值类:类org.apache.hadoop.io.Text不是类org.apache.hadoop.io.IntWritable
- 执行UDF时Pig错误1070
- 除了修改hadoop-env.sh之外,如何在hadoop中指定系统属性?
- Trunk无法编译,因为在Eclipse下使用Hadoop时libprotoc已经过时了
- 处理序列化框架的不兼容版本更改
- 以编程方式将数据批量加载到HBase的最快方法是什么?
- 在Oozie中将参数从一个动作传递到另一个动作