如何在Hadoop中读写Avro文件
时间:2020-01-09 10:34:36 来源:igfitidea点击:
在本文中,我们将介绍如何使用Java API在Hadoop中读写Avro文件。
所需的Jar包
要编写Java程序来读写Avro文件,我们需要将以下jar文件放在classpath中。我们可以将它们添加为Maven依赖项或者复制jar。
- avro-1.8.2.jar
- avro-tools-1.8.2.jar
- Hymanson-mapper-asl-1.9.13.jar
- Hymanson-core-asl-1.9.13.jar
- slf4j-api-1.7.25.jar
Java程序编写avro文件
由于使用了Avro,因此我们需要avro模式。
schema.avsc
{
"type": "record",
"name": "EmployeeRecord",
"doc": "employee records",
"fields":
[{
"name": "id",
"type": "int"
},
{
"name": "empName",
"type": "string"
},
{
"name": "age",
"type": "int"
}
]
}
Java代码
import java.io.File;
import java.io.IOException;
import org.apache.avro.Schema;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumWriter;
public class ExampleAvroWriter {
public static void main(String[] args) {
Schema schema = parseSchema();
writeToAvroFile(schema);
}
// Method to parse the schema
private static Schema parseSchema() {
Schema.Parser parser = new Schema.Parser();
Schema schema = null;
try {
// Path to schema file
schema = parser.parse(ClassLoader.getSystemResourceAsStream("resources/schema.avsc"));
} catch (IOException e) {
e.printStackTrace();
}
return schema;
}
private static void writeToAvroFile(Schema schema) {
GenericRecord emp1 = new GenericData.Record(schema);
emp1.put("id", 1);
emp1.put("empName", "Batista");
emp1.put("age", 45);
GenericRecord emp2 = new GenericData.Record(schema);
emp2.put("id", 2);
emp2.put("empName", "Jigmi");
emp2.put("age", 23);
DatumWriter datumWriter = new GenericDatumWriter(schema);
DataFileWriter dataFileWriter = null;
try {
// Local File system - out file path
File file = new File("/home/theitroad/emp.avro");
dataFileWriter = new DataFileWriter(datumWriter);
// for compression
//dataFileWriter.setCodec(CodecFactory.snappyCodec());
dataFileWriter.create(schema, file);
dataFileWriter.append(emp1);
dataFileWriter.append(emp2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(dataFileWriter != null) {
try {
dataFileWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
请注意,在此代码输出中,avro文件是在本地文件系统中创建的。如果要在HDFS中创建输出文件,则需要使用以下更改来传递路径。
// For HDFS - out file path
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create("hdfs://hostname:port/user/out/emp.avro"), conf);
OutputStream out = fs.create(newPath("hdfs://hostname:port/user/out/emp.avro"));
并在create方法中传递此OutputStream对象
dataFileWriter.create(schema, out);
在Hadoop环境中执行程序
在Hadoop环境中运行该程序之前,我们需要将上述jars放入$ HADOOP_INSTALLATION_DIR / share / hadoop / mapreduce / lib中。
如果版本不匹配,还将当前版本的Avro-1.x.x jar放在$ HADOOP_INSTALLATION_DIR / share / hadoop / common / lib位置。
要在Hadoop环境中执行上述Java程序,我们需要在Hadoop的类路径中添加包含Java程序的.class文件的目录。
export HADOOP_CLASSPATH='/huser/eclipse-workspace/theitroad/bin'
我的exampleAvroWriter.class文件位于/ huser / eclipse-workspace / theitroad / bin位置,因此我已经导出了该路径。
然后,我们可以使用以下命令运行该程序-
$ hadoop org.theitroad.ExampleAvroWriter
Java程序读取avro文件
为了读取上一个示例中存储在HDFS中的avro文件,可以使用以下方法。根据配置提供HOSTNAME和PORT的值。
private static void readFromAvroFile(Schema schema) {
Configuration conf = new Configuration();
DataFileReader dataFileReader = null;
try {
FsInput in = new FsInput(new Path("hdfs://HOSTNAME:PORT/user/out/emp.avro"), conf);
DatumReader datumReader = new GenericDatumReader(schema);
dataFileReader = new DataFileReader(in, datumReader);
GenericRecord emp = null;
while (dataFileReader.hasNext()) {
emp = dataFileReader.next(emp);
System.out.println(emp);
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(dataFileReader != null) {
try {
dataFileReader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
输出量
{"id": 1, "empName": "Batista", "age": 45}
{"id": 2, "empName": "Jigmi", "age": 23}
如果要从本地文件系统读取avro文件,则可以使用以下方法。
private static void readFromAvroFile(Schema schema) {
DataFileReader dataFileReader = null;
try {
File file = new File("/home/theitroad/emp.avro");
DatumReader datumReader = new GenericDatumReader(schema);
dataFileReader = new DataFileReader(file, datumReader);
GenericRecord emp = null;
while (dataFileReader.hasNext()) {
emp = dataFileReader.next(emp);
System.out.println(emp);
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(dataFileReader != null) {
try {
dataFileReader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

