Hadoop之Avro介紹

原文地址: itweknow.cn/detail?id=7… ,歡迎你們訪問。java

什麼是Avro

Avro是一個獨立於編程語言的數據序列化系統。這個項目由Ddoug Cutting(Hadoop之父)建立,目標是解決Hadoop中Writable類型缺少語言的可移植性的不足。Avro模式一般採用JSON來寫,數據則採用二進制格式編碼,也可採用基於JSON的數據編碼方式。編程

Avro的數據類型和模式

Avro定義了一些基本的數據類型,咱們能夠用他們來構建應用特定的數據結構。下面的表格咱們列舉了Avro的基本類型。json

類型 描述 模式示例
null 空值 "null"
boolean 二進制值 "boolean"
int 32位帶符號整數 "int"
long 64位帶符號整數 "long"
float 單精度(32位)浮點數 "float"
double 雙精度(64位)浮點數 "double"
bytes 8位無符號字節序列 "bytes"
string Unicode字符序列 "string"

還有一些複雜的類型以下表所示:數組

類型 描述 模式示例
array 一個排過序的對象集合。特定數組中的全部對象必須模式相同。 {"type": "array","items": "long"}
map 未排過序的鍵-值對。鍵必須是字符串,值能夠是任何一種類型,可是某一個map內的全部值必須模式相同。 {"type": "map", "values": "string"}
record 一個任意類型的命名字段集合。(至關於java中的自定義對象) {"type": "record", "name": "User", "doc":"A User Desc","fileds":[{"name":"nickname","type": "string"},{"name":"age","type":"int"}]}
enum 一個命名的值集合(枚舉) {"type":"enum","name":"ActionStatus","doc":"操做狀態","symbols":["SUCCESS","FAILED","ACTING"]}
fixed 一組固定數量的8位無符號字節 {"type":"fixed","name":"Md5Hash","size":16}
union 模式的並集。並集可用JSON數組表示,其中每一個元素爲一個模式。並集表示的數據必須與其內的某個模式相匹配 ["null","string",{"type":"map","values":"string"}]

Avro數據文件

前面也提到過設計Avro的目的就是解決Hadoop中Writable類型缺少語言的可移植性的不足。Avro數據文件主要是面向跨語言使用而設計的,咱們能夠經過Java寫入文件,而後經過Python來讀取文件,這都是沒有問題的。數據文件的頭部包含一個Avro模式和一個同步標識(sync marker),而後緊接着是一系列包含序列化Avro對象的數據塊。數據塊經過sync marker分隔。 這裏有兩個概念解釋一下:數據結構

  • Avro模式 - 其實就至關於對象的定義,在這裏咱們規定字段的類型以及描述等信息。
  • sync marker - 對與該文件來說是惟一的,存儲在文件頭部。

序列化和反序列化

上面也簡單的瞭解了一下Avro,下面咱們經過兩段代碼來嘗試一下Avro的序列化和反序列化。app

  • Avro模式定義,User.avsc
{
    "type": "record",
    "name": "User",
    "doc": "一個用戶",
    "fields": [
        {"name": "name", "type": "string"},
        {"name": "age", "type": "int"}
    ]
}
複製代碼
  • 序列化
@Test
public void write() throws IOException {
    Schema.Parser parser = new Schema.Parser();
    InputStream in = this.getClass().getResourceAsStream("User.avsc");
    Schema schema = parser.parse(in);
    GenericRecord record = new GenericData.Record(schema);
    record.put("name", "ganchaoyang");
    record.put("age", 23);

    File file = new File("result.avro");
    DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
    try(DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<GenericRecord>(writer)) {
        dataFileWriter.create(schema, file);
        dataFileWriter.append(record);
    }
}
複製代碼
  • 反序列化
@Test
public void read() throws IOException {
    File file = new File("result.avro");
    DatumReader<GenericRecord> reader = new GenericDatumReader<>();
    try (DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(file, reader)) {
        GenericRecord record;
        while (dataFileReader.hasNext()) {
            record = dataFileReader.next();
            Assert.assertEquals("ganchaoyang", record.get("name").toString());
            Assert.assertEquals(23, record.get("age"));
        }
    }
}
複製代碼
相關文章
相關標籤/搜索