Apache Avro

**Avro**はHadoop Hadoopで開発された行指向のRPCおよびデータシリアライゼーションフレームワークである。JSONを使用してデータ型とプロトコルを定義し、データをコンパクトなバイナリフォーマットにシリアル化する。主な用途は、永続化データのシリアル化フォーマット、Hadoopノード間の通信とHadoopサービスのクライアントプログラムのためのである。Avroはエンコードされるデータを構造化するためのスキーマを使用する。人間が編集するためのスキーマ言語（Avro IDL）とJSONを基にしたよりスキーマ言語の2種類がある。 

ThriftやProtocol Buffersに似ているが、スキーマが変更された場合でも（静的な型付き言語が必要でない限り）、コード生成プログラムを実行する必要はない。

Apache Spark SQLはデータソースとしてAvroにアクセスできる。

## Avroのオブジェクトコンテナファイル
Avroのオブジェクトコンテナファイルには次の要素から構成される。

* ファイルヘッダ
* それに続く1つ以上のデータブロック

ファイルヘッダは次の要素から構成される。

* 4倍とのASCII文字'O'、'b'、'j'と、それに続くAvroのバージョン番号1（0x01）（バイナリ値は0x4F 0x62 0x6A 0x01）。
* スキーマ定義を含むファイルメタデータ。
* ファイルごとにランダム生成された16バイト同期マーカー。

データブロックに対しては、Avroはシリアル化エンコーディングとしてバイナリとJSONの2種類が指定できる。ほとんどのアプリケーションはサイズが小さく高速なため、バイナリエンコーディングを使用している。デバッグとウェブベースのアプリケーションの場合はJSONエンコーディングが適切な場合もある。

## スキーマ定義
AvroのスキーマはJSONを使用して定義される。スキーマは、プリミティブ型（null、boolean、int、long、float、double、bytes、string）と複合型（record、enum、array、map、union、fixed）から構成される。

単純なスキーマの例:
```json
{
   "namespace": "example.avro",
   "type": "record",
   "name": "User",
   "fields": [
      {"name": "name", "type": "string"},
      {"name": "favorite_number",  "type": ["null", "int"]},
      {"name": "favorite_color", "type": ["null", "string"]}
   ] 
 }
```


## シリアライズとデシリアライズ
Avroのデータは対応するスキーマとともに保存することもできる。その場合、シリアル化されたデータ事前にスキーマを知らなくても読み込むことが可能である。

### シリアライズとデシリアライズを行うPythonコードの例
シリアライズ:
```python
import avro.schema
from avro.datafile import DataFileReader, DataFileWriter
from avro.io import DatumReader, DatumWriter

# Need to know the schema to write. According to 1.8.2 of Apache Avro
schema = avro.schema.parse(open("user.avsc", "rb").read())

writer = DataFileWriter(open("users.avro", "wb"), DatumWriter(), schema)
writer.append({"name": "Alyssa", "favorite_number": 256})
writer.append({"name": "Ben", "favorite_number": 8, "favorite_color": "red"})
writer.close()
```
ファイル`users.avro`は、以下のように、JSONのスキーマとデータのコンパクトなバイナリ表現を格納している。
```hexdump
$ od -v -t x1z users.avro 
0000000 4f 62 6a 01 04 14 61 76 72 6f 2e 63 6f 64 65 63  >Obj...avro.codec<
0000020 08 6e 75 6c 6c 16 61 76 72 6f 2e 73 63 68 65 6d  >.null.avro.schem<
0000040 61 ba 03 7b 22 74 79 70 65 22 3a 20 22 72 65 63  >a..{"type": "rec<
0000060 6f 72 64 22 2c 20 22 6e 61 6d 65 22 3a 20 22 55  >ord", "name": "U<
0000100 73 65 72 22 2c 20 22 6e 61 6d 65 73 70 61 63 65  >ser", "namespace<
0000120 22 3a 20 22 65 78 61 6d 70 6c 65 2e 61 76 72 6f  >": "example.avro<
0000140 22 2c 20 22 66 69 65 6c 64 73 22 3a 20 5b 7b 22  >", "fields": [{"<
0000160 74 79 70 65 22 3a 20 22 73 74 72 69 6e 67 22 2c  >type": "string",<
0000200 20 22 6e 61 6d 65 22 3a 20 22 6e 61 6d 65 22 7d  > "name": "name"}<
0000220 2c 20 7b 22 74 79 70 65 22 3a 20 5b 22 69 6e 74  >, {"type": ["int<
0000240 22 2c 20 22 6e 75 6c 6c 22 5d 2c 20 22 6e 61 6d  >", "null"], "nam<
0000260 65 22 3a 20 22 66 61 76 6f 72 69 74 65 5f 6e 75  >e": "favorite_nu<
0000300 6d 62 65 72 22 7d 2c 20 7b 22 74 79 70 65 22 3a  >mber"}, {"type":<
0000320 20 5b 22 73 74 72 69 6e 67 22 2c 20 22 6e 75 6c  > ["string", "nul<
0000340 6c 22 5d 2c 20 22 6e 61 6d 65 22 3a 20 22 66 61  >l"], "name": "fa<
0000360 76 6f 72 69 74 65 5f 63 6f 6c 6f 72 22 7d 5d 7d  >vorite_color"}]}<
0000400 00 05 f9 a3 80 98 47 54 62 bf 68 95 a2 ab 42 ef  >......GTb.h...B.<
0000420 24 04 2c 0c 41 6c 79 73 73 61 00 80 04 02 06 42  >$.,.Alyssa.....B<
0000440 65 6e 00 10 00 06 72 65 64 05 f9 a3 80 98 47 54  >en....red.....GT<
0000460 62 bf 68 95 a2 ab 42 ef 24                       >b.h...B.$<
0000471
```
デシリアライズ:
```python
# The schema is embedded in the data file
reader = DataFileReader(open("users.avro", "rb"), DatumReader())
for user in reader:
    print(user)
reader.close()
```
このコードの出力は次のようになる。
```python3
{'name': 'Alyssa', 'favorite_number': 256, 'favorite_color': None}
{'name': 'Ben', 'favorite_number': 8, 'favorite_color': 'red'}
```


## APIがあるプログラミング言語
理論的にはどんな言語もAvroを使用できるが、以下の言語にはすでにAPI実装が存在する:

* C
* C++
* C#
* Elixir
* Go
* Haskell
* Java
* JavaScript
* Perl
* PHP
* Python
* Ruby
* Rust
* Scala

## Avro IDL
Avroの型とプロトコル定義には、JSONのサポートに加えて、Avro IDL（旧称GenAvro）と呼ばれる実験的な代替のインタフェース記述言語（IDL）構文のサポートも提供されている。このフォーマットは、より伝統的なIDLやプログラミング言語に慣れたユーザーが簡単に適応できるように設計されており、C/C++やProtocol Buffersなどに似た構文を持つ。

## ロゴ
オリジナルのApache Avroのロゴは現在は倒産したイギリスの航空機製造会社Avro（元A.V. Roe and Company）に由来している。

Apache Avroのロゴは2023年末にオリジナルのデザインに更新された。

## 関連項目

* 
* Apache Thrift
* Protocol Buffers
* 
* Internet Communications Engine
* MessagePack
* CBOR

## 出典



## 参考文献
*