2013年7月17日水曜日

chillを使ってクラス定義変更に強いシリアライズを実現

Java向けのシリアライズライブラリであるkryoと、そのscalaラッパーのchillを使って、クラスの変更に強いシリアライズ手法の実現方法のメモです。

javaのデフォルトのシリアライズだと、SerializableVersionをきちんと付けておかないと、クラスの定義を変更しフィールドを追加した時に過去のデータから復元できなくなります。
この挙動が悪いとは言いませんが、キャッシュの際にこの挙動をされるとクラス変更をするたびにキャッシュがクリアされてしまうことになったり、不意に過去のデータがよみなくなるなど、厳密な挙動では不便な場合が多々あります。なので、kryoを使って、クラスの定義変更に強いシリアライズが出来ないか試してみました。
まず、kryoをそのまま使うと、scalaのcase classがデシリアライズ出来ないので、ここは素直にtwitter様が作ってくれているchillを使いました。
また、kryoもデフォルトではクラスのフィールドを追加したり削除したりすると、過去のデータからはシリアライズできなくなるので、少々設定をいじる必要があります。以下がその方法です。


build.sbt
scalaVersion := "2.10.0"

libraryDependencies += "com.twitter" %% "chill" % "0.2.3"

ソース

import com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer
import com.twitter.chill._

// kryoのインスタンスを取得
val kryo = KryoBijection.getKryo
// デフォルトのSerializerを、フィールド情報も保存してくれるCompatibleFieldSerializerに変更 
kryo.setDefaultSerializer( classOf[CompatibleFieldSerializer[Any]])

//新しいKryoInjectionインスタンスを作成
val Injection = KryoInjection.instance(kryo)

// シリアライズ
val bytes : Array[Byte] = Injection(Hoge(1,2,"hoge"))

// デシリアライズ
val des : Option[Any] = Injection.invert(bytes)

println(des)// Some(Hoge(1,2,"hoge"))


0 件のコメント:

コメントを投稿