Apache Avro
关于Avro
Apache Avro是一个独立于编程语言的数据化序列系统。该项目由Hadoop之父Doug Cutting创建,旨在解决Hadoop中Writable类型的不足:缺乏语言的可移植性。
1.Avro的特点
- 独立于编程语言。
- 丰富的数据结构类型。
- 快速的可压缩的二进制数据形式。(对MapReduce的输入格式至关重要。)
- Avro可用于RPC。
2.Avro数据类型和Schema
2-1.基本数据类型
类型 | 描述 | schema示例 |
---|---|---|
null | 空值 | “null” |
boolean | 二进制值 | “boolean” |
int | 32位有符号整数 | “int” |
long | 64位有符号整数 | “long” |
float | 单精度(32位)IEEE 754浮点数 | “float” |
double | 双精度(32位)IEEE 754浮点数 | “double” |
bytes | 8位无符号字节序列 | “bytes” |
string | Unicode字符序列 | “string” |
2-2.Avro复杂数据类型
类型 | 描述 | schema实例 |
---|---|---|
array | 已排序的对象集合。 | {
“type”: “array”, “items”: “long” } |
map | 未排序的键值对。key必须是string | |
record | 一个任意类型的命名字段集合 | {
“type”: “record”, “name”:“WeatherRecord”, “doc”: “A weather reading.”, “fields”: [ { “name”:“year”, “type”:“int” }, { “name”:“temperature”, “type”: “int” }, { “name”:“stationId”, “type”: “string” ] } |
ENUM | 枚举(一组命名值的集合) | {
“type”: “enum”, “name”:“Cutlery”, “doc”: “An eating utensil.”, “symbols”: [“KNIFE”, “FORK”,“SPOON”] } |
fixed | 一组固定数量的8位无符号字节 | {
“type”: “fixed”, “name”:“Md5Hash”, “size”: 16 } |
union | schema的并集(并集可以用JSON数组表示) | [ “null”, “string”, { “type”: “map”, “values”: “string” } ] |
2-3.Avro数据的读/写
2-3-1.基于schema的Avro数据读/写
首先我们需要创建一个以.avsc后缀结尾的schema文件,这里我们命名为StringPair.avsc
。
{
"namespace":"schemas",
"name":"StringPair",
"type":"record",
"doc":"This is a String Pair.",
"fields":[
{
"name":"left", "type":"string"},
{
"name":"right", "type":"string"}
]
}
namespace:可以理解为,文件创建后所在的文件夹名。
name:为文件名称,即类名称,(所以要按照java类的命名规范来命名)。
type:为Avro数据类型。
doc:为文档描述。
fields:为属性信息。
下面就是具体的demo代码:
package avro;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.avro.Schema;
import org.apache.avro.Schema.Parser;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
public class AvroDemo {
private ByteArrayOutputStream out = new ByteArrayOutputStream();
private Parser parser = new Schema.Parser();
public static void main(String[] args) throws IOException {
AvroDemo demo = new AvroDemo();
demo.writeAvroData();
demo.readAvroData();
}
public void writeAvroData() throws IOException {
Parser parser = new Schema.Parser();
Schema schema = parser.parse(getClass().getResourceAsStream("/StringPair.avsc"));
GenericRecord datum = new GenericData.Record(schema);
datum.put("left", "L");
datum.put("right", "R");
DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
writer.write(datum, encoder);
encoder.flush();
out.close();
}
public void readAvroData() throws IOException {
Schema schema = parser.parse(getClass().getResourceAsStream("/StringPair.avsc"));
ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray());
GenericDatumReader<GenericRecord> reader = new GenericDatumReader<GenericRecord>(schema);
Decoder decoder = DecoderFactory.get().binaryDecoder(input, null);
GenericRecord result = reader.read(null, decoder);
input.close();
System.out.println(result.get("left"));
System.out.println(result.get("right"));
}
}
2-3-2.基于schema生成的Avro文件,进行的数据读/写
我们可以通过schema生成StringPair类,有几种方法可以实现,这里以Maven为例。
首先,要通过配置pom.xml文件,得到我们需要的jar(Maven会根据配置信息自动下载所需要的jar文件,具体信息如下)。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM