NetflixはHollowを発表した。これはJavaライブラリとツールキットで、“ビッグデータ”のように特徴づけられていないデータセットを効率的にキャッシュできるように設計されている、このようなデータセットはEコマースや検索エンジンのためのメタデータかもしれない。もしくはNetflixの場合映画やテレビ番組のメタデータかもしれない。このようなデータセットを処理するための従来の解決策はデータストアやシリアライゼーションを使っていた。しかしおおむね信頼性とレイテンシの問題に苦しんだ。Hollowの入門の手引きではコアコンセプトと用語体系を次のように要約している。
Hollowは単一のプロデューサが構築したデータセットを管理します。そして1つ以上のコンシューマにリードオンリーのアクセスのために伝搬させます。データセットは時間の経過で変わります。データセット変更へのタイムラインは分解され個々のデータステートとなります。それぞれのデータステートは特定の時点におけるデータの完全なスナップショットです。
プロデューサとコンシューマはステートエンジンを通じてデータセットを処理する。ステートエンジンはデータステート間を推移する。プロデューサは書き込みステートエンジンを使いコンシューマは読み込みステートエンジンを使う。
HollowはNetflixの以前のインメモリデータセットフレームワークであるZenoを置き換える。データセットは今やコンパクトで固定長、データの強い型付けがあるエンコーディングで表現される。このエンコーディングはデータセットのフットプリントを最小化し、エンコードされたレコードは“再利用可能なメモリのスラブに詰められる。スラブは負荷があるサーバでのGCの振る舞いから影響を受けないようにJVMヒープにプールする”。
入門の手引き
Hollowのサンプルを始めるに当たり、次のPOJOを考える。
public class Movie {
long id;
String title;
int releaseYear;
public Movie(long id,String title,int releaseYear) {
this.id = id;
this.title = title;
this.releaseYear = releaseYear;
}
}
POJOをベースにした上記の単純なデータセットは次のように評価されるだろう。
List<Movie> movies = Arrays.asList(
new Movie(1,"The Matrix",1999),
new Movie(2,"Beasts of No Nation",2015),
new Movie(3,"Goodfellas",1990),
new Movie(4,"Inception",2010)
);
Hollowはこのmovies
リストを次のような新しいエンコーディングレイアウトに変える。
このエンコーディングについての詳細はHollowのWebサイトの上級トピックスセクションにある。
プロデューサ
プロデューサの最初のインスタンスはデータセット(この例ではmovies
)の初期データステートを公開する。コンシューマはそのデータセットを見つけるべきところで通知される。後続するデータセットへの変更は体系的にコンシューマに公開され伝達される。
プロデューサはデータセットを処理するためのものとしてHollowWriteStateEngine
を使う。
HollowWriteStateEngine writeEngine = new HollowWriteStateEngine();
HollowObjectMapper
にはHollowWriteStateEngine
を入れる。
HollowObjectMapper objectMapper = new HollowObjectMapper(writeEngine);
for(Movie movie : movies) {
objectMapper.addObject(movie);
}
HollowObjectMapper
はスレッドセーフであり並列にも実行できる。
プロデューサはデータセット(blobとして知られる)を定義したアウトプットストリームに書き込む。
OutputStream os = new BufferedOutputStream(new FileOutputStream(snapshotFile));
HollowBlobWriter writer = new HollowBlobWriter(writeEngine);
writer.writeSnapshot(os);
コンシューマ向けAPIを生成する
クライアントAPIはデータモデルに基づいた必要なJavaファイルを生成する。またコンシューマの最初のソースコードを書く前に実行しなければならない。
HollowAPIGenerator codeGenerator = new HollowAPIGenerator(
"MovieAPI", // a name for the API
"org.redlich.hollow.consumer.api.generated", // the path for generated API files
stateEngine); // the state engine
codeGenerator.generateFiles(apiCodeFolder);
コンシューマ
一度コンシューマに公開されたデータセットが通知されれば、コンシューマはデータセットへのハンドルとしてHollowWriteReadEngine
を使う。
HollowReadStateEngine readEngine = new HollowReadStateEngine();
HollowBlobReader
はblobをプロデューサからHollowReadStateEngine
へ引き渡す。
HollowBlobReader reader = new HollowBlobReader(readEngine);
InputStream is = new BufferedInputStream(new FileInputStream(snapshotFile));
reader.readSnapshot(is);
データセット内のデータは生成されたAPIでアクセスできる。
MovieAPI movieAPI = consumer.getAPI();
for(MovieHollow movie : movieAPI.getAllMovieHollow()) {
System.out.println(movie._getId() + ", " +
movie._getTitle()._getValue() + ", " +
movie._getReleaseYear());
}
これは出力した結果である。
1, "The Matrix", 1999
2, "Beasts of No Nation", 2015
3, "Goodfellas", 1990
4,"Inception", 2010
Hollowプロジェクトの全体はGitHubにある。
InfoQはDrew Koszewnik氏、NetflixのシニアソフトウェアエンジニアでHollowのリードコントリビュータとの、Hollowの具体的な実装詳細に関する詳細なインタビューを取り上げている。
Rate this Article
- Editor Review
- Chief Editor Action