Avro is a row-oriented remote procedure call and data serialization framework developed within Apache's Hadoop project. It uses JSON for defining data types and protocols, and serializes data in a compact binary format. Its primary use is in Apache Hadoop, where it can provide both a serialization format for persistent data, and a wire format for communication between Hadoop nodes, and from client programs to the Hadoop services.
Avro uses a schema to structure the data that is being encoded. It has two different types of schema languages; one for human editing (Avro IDL) and another which is more machine-readable based on JSON.

It is similar to Thrift and Protocol Buffers, but does not require running a code-generation program when a schema changes (unless desired for statically-typed languages).

Apache Spark SQL can access Avro as a data source.

Avro Object Container File

An Avro Object Container File consists of: 
 A file header, followed by
 one or more file data blocks.

A file header consists of:
 Four bytes, ASCII 'O', 'b', 'j', followed by the Avro version number which is 1 (0x01) (Binary values 0x4F 0x62 0x6A 0x01).
 File metadata, including the schema definition.
 The 16-byte, randomly-generated sync marker for this file.

For data blocks Avro specifies two serialization encodings: binary and JSON. Most applications will use the binary encoding, as it is smaller and faster.  For debugging and web-based applications, the JSON encoding may sometimes be appropriate.

Schema definition 
Avro schemas are defined using JSON.  Schemas are composed of primitive types (null, boolean, int, long, float, double, bytes, and string) and complex types (record, enum, array, map, union, and fixed).

Simple schema example:
 {
   "namespace": "example.avro",
   "type": "record",
   "name": "User",
   "fields": [
      {"name": "name", "type": "string"},
      {"name": "favorite_number",  "type": ["null", "int"]},
      {"name": "favorite_color", "type": ["null", "string"]}
   ] 
 }

Serializing and deserializing 
Data in Avro might be stored with its corresponding schema, meaning a serialized item can be read without knowing the schema ahead of time.

Example serialization and deserialization code in Python 
Serialization:
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()

File "users.avro" will contain the schema in JSON and a compact binary representation of the data:

$ 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

Deserialization:

# The schema is embedded in the data file
reader = DataFileReader(open("users.avro", "rb"), DatumReader())
for user in reader:
    print(user)
reader.close()

This outputs:

{u'favorite_color': None, u'favorite_number': 256, u'name': u'Alyssa'}
{u'favorite_color': u'red', u'favorite_number': 8, u'name': u'Ben'}

Languages with APIs 
Though theoretically any language could use Avro, the following languages have APIs written for them:
C
C++
C#
Elixir
Go
Haskell
Java
Javascript
Perl
PHP
Python
Ruby
Rust
Scala

Avro IDL
In addition to supporting JSON for type and protocol definitions, Avro includes experimental support for an alternative interface description language (IDL) syntax known as Avro IDL.  Previously known as GenAvro, this format is designed to ease adoption by users familiar with more traditional IDLs and programming languages, with a syntax similar to C/C++, Protocol Buffers and others.

Logo
The Apache Avro logo is from the defunct British aircraft manufacturer Avro (originally A.V. Roe and Company). Football team Avro F.C. uses the same logo.

See also

 Comparison of data serialization formats
 Apache Thrift
 Protocol Buffers
 Etch (protocol)
 Internet Communications Engine
 MessagePack
 CBOR

References

Further reading
 

Apache Software Foundation projects
Inter-process communication
Application layer protocols
Remote procedure call
Data serialization formats
Articles with example Python (programming language) code
아브로(Avro)는 아파치의 하둡 프로젝트에서 개발된 원격 프로시저 호출(RPC) 및 데이터 직렬화 프레임워크이다. 자료형과 프로토콜 정의를 위해 JSON을 사용하며 콤팩트 바이너리 포맷으로 데이터를 직렬화한다. 주 용도는 아파치 하둡에서 클라이언트→하둡 서비스에 대해 영구 데이터를 위한 직렬화 포맷과 하둡 노드 간 통신을 위한 와이어 포맷을 둘 다 제공하는 것이다.

스리프트나 프로토콜 버퍼와 비슷하지만 스키마 변경이 발생할 때(정적 자료형 언어를 위해 요구되지 않을 경우) 코드 생성 프로그램의 실행을 요구하지 않는다.

아파치 스파크 SQL은 데이터 소스로서 아브로에 접근할 수 있다.

아브로 오브젝트 컨테이너 파일 
아브로 오브젝트 컨테이너 파일은 다음으로 구성된다:
 파일 헤더
 (파일 헤더에 이어서) 하나 이상의 파일 데이터 블록

파일 헤더는 다음으로 구성된다:
 4바이트, ASCII 'O', 'b', 'j', 그리고 1.
 파일 메타데이터 (스키마 정의 포함)
 16바이트, 이 파일을 위해 임의 생성된 동기화 마커.

데이터 블록의 경우 아브로는 2개의 직렬화 인코딩을 규정한다: 바이너리, JSON. 대부분의 응용 프로그램들은 크기가 더 작고 더 빠르다는 이유로 이진 인코딩을 사용한다. 디버깅 및 웹 기반 애플리케이션의 경우 JSON 인코딩이 적절할 수 있다.

스키마 정의 
아브로 스키마는 JSON을 사용하여 정의된다. 스키마는 원시 자료형(null, boolean, int, long, float, double, bytes, string)과 복소수 자료형(record, enum, array, map, union, and fixed)으로 구성된다.

단순 스키마 예제:
 {
   "namespace": "example.avro",
   "type": "record",
   "name": "User",
   "fields": [
      {"name": "name", "type": "string"},
      {"name": "favorite_number",  "type": ["int", "null"]},
      {"name": "favorite_color", "type": ["string", "null"]}
   ]
 }

직렬화와 역직렬화 
아브로의 데이터는 상응하는 스키마와 함께 저장할 수 있으며, 즉 미리 스키마를 알지 않고도 직렬화된 항목을 읽을 수 있다는 이야기가 된다.

파이썬의 직렬화, 역직렬화 코드 예제 
예제는 다음과 같다.

직렬화:
import avro.schema
from avro.datafile import DataFileReader, DataFileWriter
from avro.io import DatumReader, DatumWriter

schema = avro.schema.parse(open("user.avsc").read())  # need to know the schema to write

writer = DataFileWriter(open("users.avro", "w"), DatumWriter(), schema)
writer.append({"name": "Alyssa", "favorite_number": 256})
writer.append({"name": "Ben", "favorite_number": 7, "favorite_color": "red"})
writer.close()

"users.avro" 파일은 JSON 및 콤팩트 바이너리 표현 데이터의 스키마를 포함할 것이다:

$ od -c users.avro
0000000    O   b   j 001 004 026   a   v   r   o   .   s   c   h   e   m
0000020    a 272 003   {   "   t   y   p   e   "   :       "   r   e   c
0000040    o   r   d   "   ,       "   n   a   m   e   s   p   a   c   e
0000060    "   :       "   e   x   a   m   p   l   e   .   a   v   r   o
0000100    "   ,       "   n   a   m   e   "   :       "   U   s   e   r
0000120    "   ,       "   f   i   e   l   d   s   "   :       [   {   "
0000140    t   y   p   e   "   :       "   s   t   r   i   n   g   "   ,
0000160        "   n   a   m   e   "   :       "   n   a   m   e   "   }
0000200    ,       {   "   t   y   p   e   "   :       [   "   i   n   t
0000220    "   ,       "   n   u   l   l   "   ]   ,       "   n   a   m
0000240    e   "   :       "   f   a   v   o   r   i   t   e   _   n   u
0000260    m   b   e   r   "   }   ,       {   "   t   y   p   e   "   :
0000300        [   "   s   t   r   i   n   g   "   ,       "   n   u   l
0000320    l   "   ]   ,       "   n   a   m   e   "   :       "   f   a
0000340    v   o   r   i   t   e   _   c   o   l   o   r   "   }   ]   }
0000360  024   a   v   r   o   .   c   o   d   e   c  \b   n   u   l   l
0000400   \0 211 266   / 030 334   ˪  **   P 314 341 267 234 310   5 213
0000420    6 004   ,  \f   A   l   y   s   s   a  \0 200 004 002 006   B
0000440    e   n  \0 016  \0 006   r   e   d 211 266   / 030 334   ˪  **
0000460    P 314 341 267 234 310   5 213   6
0000471

역직렬화:

reader = DataFileReader(open("users.avro", "r"), DatumReader())  # no need to know the schema to read
for user in reader:
    print user
reader.close()

위의 출력은 다음과 같다:

{u'favorite_color': None, u'favorite_number': 256, u'name': u'Alyssa'}
{u'favorite_color': u'red', u'favorite_number': 7, u'name': u'Ben'}

API 사용 언어 
이론적으로 모든 언어가 아브로를 사용할 수 있으나 다음의 언어가 API를 갖추고 있다:
 C
 C++
 C#
 Go
 하스켈
 자바
 펄
 PHP
 파이썬
 루비
 스칼라

아브로 IDL 
자료형 및 프로토콜 정의를 위해 JSON을 지원하는 것 외에도 아브로는 아브로 IDL(Avro IDL)이라는 이름의 인터페이스 정의 언어(IDL) 문법의 실험적인 지원을 포함하고 있다. 과거에는 GenAvro라는 이름이었던 이 포맷은 C/C++, 프로토콜 버퍼 등과 비슷한 문법을 갖춘 더 전통적인 IDL, 프로그래밍 언어에 친숙한 사용자들에 의해 쉽게 채용되도록 설계되어 있다.

같이 보기 
 데이터 직렬화 포맷 비교
 아파치 스리프트
 프로토콜 버퍼
 CBOR

각주

추가 문헌 
 

프로세스 간 통신
응용 계층 프로토콜
원격 프로시저 호출
데이터 직렬화 포맷
아파치 소프트웨어 재단 프로젝트