Apache Avro について知っていることを書いていく その1
Apache Avro になにかと縁があり、かつ普及しているテクノロジーの割に日本語の情報がそんなにない(個人の意見です、意外とあるかも)のでつらつら書いてみます。 整理はされておらずシーケンシャルに要素を並べています。 実装についてとくに言及がされていなければ、 Java の 1.8.2 について触れているものとします。
Apache Avro はデータフォーマットとエコシステムのひとつ
Apache Avro は Apache トップレベルプロジェクトのひとつでファイルフォーマットとその周辺エコシステムです。 比較される技術として Protocol Buffers や Message Pack が挙げられると思います。 Apache Avro はそれらの中でも主に Hadoop エコシステムなどビッグデータ絡みの文脈でよく登場するように思えます。
以下のディレクトリ構成の通り、公式でいくつかのプログラミング言語をサポートしているようです。
筆者はほとんど Java のパッケージしか使わず正確な比較も行ってないのですが、おそらく Java 向けの機能がサポート厚めだと思われます。
avro-tools
が Java で書かれてたり avro-protobuf
という Protocol Buffers との変換ライブラリが提供されていたりするので。
また非公式ですが以下のような他言語向けライブラリもあったりします。
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 で記述することになる上か結構冗長でかつ人間にとって読みにくい内容になりがちです。 公式リポジトリに簡単な例があるのですが、簡単なものでもある程度事前知識を求められるでしょう。 さらに型をネストし始めたら地獄です。 筆者は特殊な訓練を繰り返すことにより最近手でスキーマを書けるようになってきた気がしますが、このスキーマの記載を同僚に求めるのは酷なものです。
この問題はかなり認知されているのか、公式が IDL を提供しています。 一見 Protocol Buffers を彷彿とさせる気がするシンタックスですね。
また、プログラムから動的にスキーマを記述、生成することもできます。
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 などと組み合わせてフィルタしたり内容確認できたりして便利ですね。
飽きてきたので
本記事ではこれくらいにしておきます。 気力があったり次回書きたいことがまとまってきたらまた書きます。