# Apache Avro ## 概要 Apache Avro は 2009 年に Hadoop のサブプロジェクトとして始まったバイナリエンコーディング形式。[[Protocol Buffers]] が Hadoop の用途に合わなかったことがきっかけで開発された。人間の編集用の Avro IDL と、機械可読な JSON ベースのスキーマ表現の2つのスキーマ言語を持つ。例示レコード(`userName`・`favoriteNumber`・`interests`)を符号化すると 32 バイトで、本書が比較した中で最もコンパクトである。スキーマにタグ番号を持たず、符号化データにはフィールド名・型注釈・長さ以外のメタ情報を含まない値の連結のみが現れるため、デコードには符号化時とまったく同じスキーマが必要になる。(Source: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 5 Encoding and Evolution]] "Avro") ## writer's schema と reader's schema エンコード側が使うスキーマを writer's schema、デコード側が期待するスキーマを reader's schema と呼び分ける。両者が異なる場合、Avro はフィールド名で対応付けて差分を解決する: reader にしかないフィールドはデフォルト値で埋め、writer にしかないフィールドは無視する。互換性を保てるのは**デフォルト値を持つフィールドの追加・削除のみ**で、`null` を許すには `union { null, ... }` 型の先頭分岐に `null` を置く必要がある。フィールド名の変更はエイリアスで吸収でき後方互換だが前方互換ではない。writer's schema をどう読み手に伝えるかは用途依存で、(1) 大量レコードを含む単一ファイルなら先頭に一度だけ埋め込む(object container file)、(2) 個別に書かれるレコードなら DB にスキーマバージョンの一覧を保持しレコードにバージョン番号だけ付与する([[分散メッセージブローカ|Apache Kafka]] 向け Confluent Schema Registry や LinkedIn Espresso が採用)、(3) 双方向コネクションなら接続確立時にスキーマバージョンをネゴシエートする、の3パターンがある。(Source: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 5 Encoding and Evolution]] "The writer's schema and the reader's schema", "But what is the writer's schema?") ## 動的生成スキーマとの親和性 Avro のスキーマにはタグ番号がないため、リレーショナルデータベースのスキーマから自動生成しやすい。DB スキーマが変わるたびに Avro スキーマを再生成してダンプすればよく、読み手は新しい writer's schema を古い reader's schema と名前突き合わせで解決できる。対照的に [[Protocol Buffers]] ではフィールドタグをスキーマ生成器が手動または慎重な自動割り当てで管理する必要があり、動的生成スキーマへの適合性は設計目標ではなかった。(Source: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 5 Encoding and Evolution]] "Dynamically generated schemas") ## 関連 - ソース: [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 5 Encoding and Evolution]] - エンティティ: [[Protocol Buffers]] - 概念: [[スキーマ発展]] / [[バイナリエンコーディング]] ## 出典 - [[@2026__OReilly__Designing Data-Intensive Applications 2E - Chapter 5 Encoding and Evolution]]("Avro", "The writer's schema and the reader's schema", "Dynamically generated schemas")