ブログのしゅーくりーむ

技術的なメモとかライフログとか。

Apache Avro について知っていることを書いていく その1

Apache Avro になにかと縁があり、かつ普及しているテクノロジーの割に日本語の情報がそんなにない(個人の意見です、意外とあるかも)のでつらつら書いてみます。 整理はされておらずシーケンシャルに要素を並べています。 実装についてとくに言及がされていなければ、 Java の 1.8.2 について触れているものとします。

Apache Avro はデータフォーマットとエコシステムのひとつ

Apache AvroApache トップレベルプロジェクトのひとつでファイルフォーマットとその周辺エコシステムです。 比較される技術として Protocol Buffers や Message Pack が挙げられると思います。 Apache Avro はそれらの中でも主に Hadoop エコシステムなどビッグデータ絡みの文脈でよく登場するように思えます。

以下のディレクトリ構成の通り、公式でいくつかのプログラミング言語をサポートしているようです。

github.com

筆者はほとんど Java のパッケージしか使わず正確な比較も行ってないのですが、おそらく Java 向けの機能がサポート厚めだと思われます。 avro-toolsJava で書かれてたり avro-protobuf という Protocol Buffers との変換ライブラリが提供されていたりするので。 また非公式ですが以下のような他言語向けライブラリもあったりします。

github.com

Avro はスキーマの表現力が強い

Avro はスキーマに従いシリアライゼーションとでシリアライゼーションをするわけですが、このスキーマの表現力が割と強いです。 雑に列挙すると以下の通りです。

  • record 型(構造体)のサポート

    • エイリアスや doc 、 namespace の宣言もできる(オプション)
  • array 型(配列)のサポート

  • union 型(共用体)のサポート

    • null 型との union を取り、デフォルト値を null にすることで nullable な型を表現できる
  • map 型のサポート

  • enum 型のサポート
  • fixed 型という固定長バイト配列のサポート(使ったこと無いのでよくわからん)
  • デフォルト値が設定できる
  • logical types を使うことで型に別の解釈をもたせることができる

    • メジャーな使い方として long 型に timestamp-millis logical type をもたせるなど
    • timestamp の制度は micros も選べる

これらにより、かなりリッチなスキーマを記述することができるはずです。

Avro のスキーマを記述するのがつらい

表現力が高いこともあるのですが、基本的にスキーマJSON で記述することになる上か結構冗長でかつ人間にとって読みにくい内容になりがちです。 公式リポジトリに簡単な例があるのですが、簡単なものでもある程度事前知識を求められるでしょう。 さらに型をネストし始めたら地獄です。 筆者は特殊な訓練を繰り返すことにより最近手でスキーマを書けるようになってきた気がしますが、このスキーマの記載を同僚に求めるのは酷なものです。

github.com

この問題はかなり認知されているのか、公式が IDL を提供しています。 一見 Protocol Buffers を彷彿とさせる気がするシンタックスですね。

avro.apache.org

また、プログラムから動的にスキーマを記述、生成することもできます。 Java であれば Schema.createRecord() して List<Schema.Field> オブジェクトを埋めて・・・といった流れで実現できます。

Avro 自体の圧縮効率はそんな高くない?

int, long は zigzag encoding してくれますが、 bytes, string は length + バイナリなどかなりシンプルなシリアライズをします。 結果としてシリアライズされたあとのバイナリのサイズは Protocol Buffers や Message Pack と比較してそんなに潰れないと思います。 (実測した訳でなく、単にこれまでの経験則程度の話です) ただ Object Container Files フォーマットを取るとブロック単位に圧縮をかけてくれたりします。

Object Container Files フォーマットの便利さ

あなたがデータアナリストやデータサイエンティストなどのポジションで働いているなら、このフォーマットで Avro と対面することが多いかもしれません。 .avro 拡張子をよく取る、 Object Container Files フォーマットに従うレイアウトを取ったファイルです。

実体は well-known な Avro スキーマに従ってシリアライズされたファイルになります。 そのスキーマの中にはレコードのスキーマとコーデック、フィンガープリント情報などが含まれます、 ここのスキーマ情報により、ファイルを読むことで中のバイナリがどんなスキーマシリアライズされたかわかるので動的にデシリアライザを生成して読める状態になってるわけですね!すぐれもの!

このファイルフォーマットは BigQuery や Redshift でもサポートされており、 Hadoop エコシステムにあまり関わらずとも Avro のファイルをオブジェクトストレージに書き出しておけば、あとで DHW に統合して安全便利にクエリを投げられるわけですね!すぐれもの!

avro-tools が開発運用に便利

あまり言及されてない気がしますが、 avro-tools という Java 製のツールが便利です。 事前定義した Avro のスキーマを記載した.avsc ファイルから Specific クラスを自動生成するのはもちろん、 Object Container Files フォーマットのファイルから schema を読んで吐いてくれたりレコードを json に変換して出力してくれたりします。 特にレコードを json で出力してくれると、 jq などと組み合わせてフィルタしたり内容確認できたりして便利ですね。

mvnrepository.com

飽きてきたので

本記事ではこれくらいにしておきます。 気力があったり次回書きたいことがまとまってきたらまた書きます。