Avro简单笔记介绍

Apache Avero是一个独立于编程语言的数据序列化系统,有一个被多种语言处理的数据格式。Avro的特点是,代码生成可选,意味着可以对遵循制定模式的数据进行读写操作。Avro通常采用JSON编写,数据通常用二进制格式编码。

 

Avro规范精确定义所有实现必须支持二进制格式。它有丰富的数据模式解析能力。在约束条件下,读数据模式不必与写数据模式相同。除此之外,其为一系列对象制定一个对象容器格式——类似与hadoop的顺序文件,还可以用于RPC,支持滚动升级,对多语言客户端进行支持。

 

Avro数据类型和格式:(补图)

 

1.所有的语言转到Avro语言API都可以使用动态映射,JAVA成为“通用”映射;

2.java和C艹可以自动生成代码来表示符合某一Avro模式的数据,java中成为“特殊”映射;

3.java拥有第三类“自反映射”,能够将Avro类型映射称实现已有的java类型,但是速度较前两种都慢

 

Avro数据文件

Avro的对象容器文件格式主要用于存储Avro对象序列

数据文件的头部分包含元数据,包括一个Avro模式和一个sync marker,紧接着是一系列包含序列化Avro对象的数据块。Avro数据文件是可切分的,适合MapReduce的快速处理。

 

可以使用不同的语言写入和读取Avro数据,可以选择与写入数据模式不同的模式来都会数据模式。

 

基于文件的数据结构

SequenceFile

考虑日志文件,其中每一条日志记录是一行文本。它同样可以座位小文件的容器。

SequenceFile的写操作

通过createWriter()静态方法可以创建SequenceFile对象,并返回SequenceFile.Writer实例。拥有SequenceFile.Writer实例之后就可以使用append()方法在文件末尾附加键/值对。写完之后可以调用close()方法结束。

写入SequenceFile对象示例代码:


public class SequenceFileWriteDemo{
    private static final String[] DATA={
        "One, two,buckle my shoe",
        "Three, four shu the door"};
    public static void main(String[] args){
        String uri = args[0];
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(URI.create(uri), conf);
        Path path = new Path(uri);
        IntWritable key = new IntWritable();
        Text value = new Text();
        SequenceFile.Writer writer = null;
        try{
            writer = SequenceFile.createWriter(fs, conf, path, key.getClass(),   value.getClass());
            for(int i = 0; i<100; i++){
                key.set(100 - i);
                value.set(DATA[i % DATA.length]);
                System.out.println("[%s]\t%s\t%s\n", writer.getLength(), key, value);
                writer.append(key, value);
            }
        }finally{
            IOUtils.closeStream(writer);
        }
    }
}

其中,key的类型为IntWritable,value的类型为Text。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Apache Avro是一个数据序列化系统,旨在支持快速、节省空间的数据交换和远程过程调用。它使用JSON格式定义数据结构,并支持动态类型,使其易于在不同编程语言之间进行交互。 使用Avro的步骤如下: 1. 定义数据结构:使用Avro的JSON格式定义数据结构,包括字段名、类型和默认值等信息。 例如,定义一个Person对象: ``` { "namespace": "example.avro", "type": "record", "name": "Person", "fields": [ {"name": "name", "type": "string"}, {"name": "age", "type": "int"} ] } ``` 2. 生成代码:使用Avro工具生成指定语言的代码,包括数据结构类和序列化/反序列化类等。 例如,使用Avro工具生成Java代码: ``` $ java -jar avro-tools-1.9.2.jar compile schema person.avsc . ``` 3. 序列化数据:使用生成的代码将数据序列化为字节数组。 例如,使用Java代码创建Person对象并序列化: ``` Person person = new Person("Alice", 30); ByteArrayOutputStream out = new ByteArrayOutputStream(); DatumWriter<Person> writer = new SpecificDatumWriter<Person>(Person.class); Encoder encoder = EncoderFactory.get().binaryEncoder(out, null); writer.write(person, encoder); encoder.flush(); byte[] bytes = out.toByteArray(); ``` 4. 反序列化数据:使用生成的代码将字节数组反序列化为数据对象。 例如,使用Java代码反序列化字节数组: ``` ByteArrayInputStream in = new ByteArrayInputStream(bytes); DatumReader<Person> reader = new SpecificDatumReader<Person>(Person.class); Decoder decoder = DecoderFactory.get().binaryDecoder(in, null); Person person2 = reader.read(null, decoder); ``` 这样,就完成了数据的序列化和反序列化。 以下是一个完整的Java代码示例: ``` import org.apache.avro.Schema; import org.apache.avro.Schema.Parser; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericRecord; import org.apache.avro.io.DatumReader; 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; import org.apache.avro.specific.SpecificDatumReader; import org.apache.avro.specific.SpecificDatumWriter; import org.apache.avro.specific.SpecificRecord; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public class AvroExample { public static void main(String[] args) throws IOException { // Define schema String schemaJson = "{\n" + " \"namespace\": \"example.avro\",\n" + " \"type\": \"record\",\n" + " \"name\": \"Person\",\n" + " \"fields\": [\n" + " {\"name\": \"name\", \"type\": \"string\"},\n" + " {\"name\": \"age\", \"type\": \"int\"}\n" + " ]\n" + "}"; Schema schema = new Parser().parse(schemaJson); // Serialize data Person person = new Person("Alice", 30); ByteArrayOutputStream out = new ByteArrayOutputStream(); DatumWriter<Person> writer = new SpecificDatumWriter<Person>(Person.class); Encoder encoder = EncoderFactory.get().binaryEncoder(out, null); writer.write(person, encoder); encoder.flush(); byte[] bytes = out.toByteArray(); // Deserialize data ByteArrayInputStream in = new ByteArrayInputStream(bytes); DatumReader<Person> reader = new SpecificDatumReader<Person>(Person.class); Decoder decoder = DecoderFactory.get().binaryDecoder(in, null); Person person2 = reader.read(null, decoder); System.out.println(person2.getName()); // Alice System.out.println(person2.getAge()); // 30 } public static class Person implements SpecificRecord { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } @Override public void put(int i, Object o) { } @Override public Object get(int i) { if (i == 0) { return name; } else if (i == 1) { return age; } return null; } @Override public Schema getSchema() { return null; } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值