つかびーの技術日記

情報系修士卒のWeb系技術日記です。現在のフォーカス分野はアドテクです。

Avroでデータのserialize, deserializeをする(Java, Scala)

   

こんにちは、@s_tsukaです。

今回はAvroのシリアライザの話です。

こちらの記事ではAvroのsbtプラグインを使って、entityクラスを自動生成する方法を紹介しました。

Avroは単なるスキーマではなく、シリアライズ・デシリアライズのシステムでもあります。むしろシリアライズこそが本命の機能であると言って良いでしょう。そこが非常に強力です。

今回はそのシリアライズまわりについて触れていきます。

Avro公式のJavaライブラリでシリアライズ

AvroをJavaで利用する場合は、公式のライブラリおよびDocumentが利用できます。

http://avro.apache.org/docs/current/gettingstartedjava.html

MavenやSBTで

こちらのjarの依存を追加するだけです。

利用方法は上記のドキュメントGettingStartedを参考にすると良いと思います。もちろんScalaでも使えます。

Codeの自動生成を併用するタイプと、コードの自動生成を併用しない2つのタイプがあります。どちらも基本的にはこのあたりのコードのように

dataFileWriteを通して書き込み(append)を行うだけです。

ファイルの先頭にスキーマが、その後にデータがバイナリ形式で書き込まれます。

上の方の自動生成を併用するタイプだとuserオブジェクトをそのままappendできて大変簡潔ですが、下の方のだとGenericRecordにする必要があります。外部から来た(予めクラスを作れない・動的な)データをAvro形式で書き込みたいときは後者を採用することになると思います。

デシリアライズもサンプルが載っているのでそれに従えば良いだけです。

avro4sでシリアライズ

https://github.com/sksamuel/avro4s

自分が調べた限りではavro4sが最も開発が盛んで安定していると思います。

他にもGenslerAppsPod/scalavroもありますが、こちらは開発が停滞しており2016/9/15時点でScala 2.11のjarが存在しません。avro4sのほうが良いと思います。

こちらも使い方は単純でjarの依存を追加するだけです。ほぼREADME通りで良いです。循環参照が発生するクラスについてはRecursive Schemasの節の通り、ちょっとしたimplicitとSchemaForを使う必要があるので注意です。

RecordFormatのto, fromメソッドを利用することでGenericRecordオブジェクトを生成することができますが、AvroOutputStreamでGenericRecordを書き込むことはできません。このあたりは先述のAvro公式JavaライブラリのGenericDatumWriterを使うしかなさそうです。

公式とほぼ同じですがサンプルコードです。

お手軽ですね。

avro4sを使えば、確かにScalaでもAvroを上手く使うことができますが、case classを作らなかったり、スキーマが動的に変わるシーンなどでは、必ずしもavro4sを使わなくても良いとは思います。

とはいえ、avro4sはJavaのavroライブラリを内包しているので、avro4s使っておけば間違い無いと思います。

Avroに対応しているソフトウェアはまだまだ少ない方ですが、革新的なフォーマットだと思うので、みなさん使っていきましょう。

 - Java, Scala, ライブラリ ,