SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

初めてのHBase

HBaseを使ってグラフDBを作ってみよう(中編)

初めてのHBase 第6回

  • X ポスト
  • このエントリーをはてなブックマークに追加

実装

 それでは、実際にコードを書いていきましょう。今回も、GitHubにソースコードを上げていますので、こちらをベースに説明していきます。

 今回は機能追加ということで、前回作成したクラスを継承する形で実装をしています。

リレーションシップの作成

 最初にリレーションシップの作成するコードです。

 リレーションシップの作成時にセカンダリインデックスを作成します。Github上では以下のURLです。

 リレーションシップRowとリレーションシップの最新順インデックスRowに関しては前回と同じです。

 プロパティごとに、方向(INCOMING、OUTGOING)×順序(ASC、DESC)の4つのセカンダリインデックスのRowをPutします。

  • 91~105行目で、各プロパティについてセカンダリインデックスのPutオブジェクトを作成しています。
  • 108行目で、最新順インデックスRowと同時に、batchでPutしています。

リレーションシップの削除

 次にリレーションシップの削除するコードです。

 リレーションシップの作成時に、セカンダリインデックスを作成します。Github上では以下のURLです。

 リレーションシップの作成と同様に、リレーションシップRowとリレーションシップの最新順インデックスRowに関しては前回と同じです。

  • 196~209行目で、各プロパティについてセカンダリインデックスのDeleteオブジェクトを作成しています。
  • 212行目で、最新順インデックスRowと同時に、batchでDeleteしています。

リレーションシップのプロパティの更新・削除時

 リレーションシップのプロパティの更新・削除時のコードは、Github上では以下のURLです。

 こちらも、リレーションシップRowとリレーションシップの最新順インデックスRowに関しては前回と同じです。

 セカンダリインデックスでは、RowKeyにリレーションシップの値が含まれているので、それが更新・削除されたときに、セカンダリインデックスのRowを削除・追加する必要があります。これは、最新順インデックスでは必要ありませんでした。

 ここで、今回作成しているグラフDBのもう一つの整合性の問題について書きます。先程も書いたように、HBaseは基本的にはRow内のトランザクションしかサポートしていないので、Rowの削除・追加はアトミックに行われません。セカンダリインデックスの更新時に、それを使用した隣接リレーションシップの取得をすると、不整合な状態が見えてしまいます。

 この不整合な状態は、削除・追加を行う順番によって2種類存在します。

 削除してから追加を行うと、一瞬だけ更新されたリレーションシップがなくなったように見えます。追加してから削除を行うと、一瞬だけ更新されたリレーションシップが2つあるように見えます。

 今回作成しているグラフDBでは、追加してから削除を行い、2重で取得されてしまった場合に片方を結果に含めないことで、この不整合問題を対処しています。

 実際に取得する際には、件数を限定して取る場合がほとんどなので、その中で2重で取得されてしまった場合のみに片方を結果に含めないようにします。このようにすることで、片方を結果に含めないという処理の負荷を軽減しています。

 それでは、コードの説明に戻ります。

  • 395~418行目でセカンダリインデックスのPutオブジェクトを作成しています。
  • 420~432行目でセカンダリインデックスのDeleteオブジェクトを作成しています。
  • 435~440行目で先程の不整合問題に対処するために、まずbatchでPutしてから、その後にDeleteをしています。

隣接リレーションシップの取得(セカンダリインデックスを使用)

 最後に、隣接リレーションシップをセカンダリインデックスを用いて取得するコードです。

 FilterやSortによってどのセカンダリインデックスを使うかを選択し、Scanをかけるという流れになっています。具体的にFilterやSortによってどのセカンダリインデックスを使うかを選択する処理は、実装レベルではScanのstartRowとstopRowをどのように決めるかという話になります。この処理は、createSecondaryIndexScanで行っています。

 簡単に説明すると、Sortによって、昇順用のセカンダリインデックスを使うか、あるいは降順用のセカンダリインデックスを使うかを決めます。さらに、FilterのOperatorによって、セカンダリインデックスのどの範囲をScanするかを導き出し、startRowとstopRowを決めています。

 この処理の詳細については、多少複雑になっていますが、実際にコードを読んでみるとお分かりいただけると思います。また、247行目のSet型のnodeIdSetを用いることで、すでに結果に入っているノードIDを結果に含めない処理を行っています。

 これは、先ほど書いたセカンダリインデックスの不整合問題に対処するためです。

まとめ

 今回は、前回作成したグラフDBにリレーションシップのプロパティによるセカンダリインデックス機能を追加しました。

 Row内のみという限定されたトランザクションしかないHBaseにおいて、どのようにセカンダリインデックスを実現するかについて参考になれば幸いです。

 次回は、さらに別の機能を追加していきたいと思います。

 また、株式会社サイバーエージェントでは、Hadoop/HBaseエンジニアを募集しています。ご興味のある方はこちらからエントリーしていただければと思います。エンジニア>R&Dエンジニア>R&Dエンジニアを選択しエントリーしていただければ幸いです。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
初めてのHBase連載記事一覧

もっと読む

この記事の著者

鈴木 俊裕(スズキ トシヒロ)

株式会社サイバーエージェント アメーバ事業本部 Ameba Technology Laboratory 2008年4月に株式会社サイバーエージェントに新卒で入社。基盤システムの開発・運用に従事する。 2010年4月にHadoop/Hiveを用いたログ解析基盤の開発・運用を担当する。 2011年4月に、ログ解析、レコメンド、検索エンジンなどを開発するAmeba Technology Laboratoryの立ち上げメンバーとなる。 2011年10月からHBaseを用...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7486 2013/11/15 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング