LINE DEVELOPER DAY 2016に今年も今年も参加してきたのでそのメモです。
Gravty “A scalable graph database to traverse large-scale relationship fast”
LINE+ 開発7室 Lee KyoungBok様, Kim Hoonmin様
- GravityはGraph Databaseです
- Graph Databaseはストレージ,グラフの検索能力が使える
- GraphDatabase技術を取り入れたのがGoogleやFB
- 商品のリコメンデーションの仕組みに採用されていたりする
- LINEサービスがどんどん増えており、より効率よくクエリーをかける必要があるので、独自のグラフデータベースであるGravtyを開発した
- LINEのタイムラインだけを見ても膨大な情報がある
- Gravtyは一言で言えばスケーラビリティで、リレーショナルデータを効率よく格納して検索できる
- サービスニーズは予測できない形で変化するので、うまくコントロールする必要がある
- 要件としてはスケールアウトが可能なこと、開発者にとって開発しやすく、クライアントサイドにとっても使いやすいものでないといけない
Gravtyについて
- GravtyはDBの枠組みのフィールドワークエリアでできていて、TinkerPopを用いたGraphDBのフレームワークを使っている
- Gravtyの中ではApacheのPhoneixをHBaseのセカンダリのインデックスとして使っている
- ストレージレイヤーにはPhoneixリポジトリを持っている
- イベントのストーリーミングに対しても使用可能
- 良いモデルがないとちゃんとDBにならない
- テーブルの設計はスケールアップを考えて使わないといけない
DataModelについて
Flat-Wide Table
- エッジとプロパティでストレージのカラムを行う
- カラムにエッジは保存される
- 問題としてはカラムのスキャンをしないといけない(遅い)、カラムのスプリットが出来ない
Tall-Narrow Table
- GravtyではTall-Narrow Tableというのを使っている
- 列の方にエッジを保存する
- source vertex propertyももっている
- Hbaseはrowでsplitをおこなうため、HBaseを使う場合はよい選択
- パラレルで平行に処理するのもこちらのほうがよい
- ApacheのTinkerPopのグレムリンを使っている
それぞれのモデルの検索方法について
- Flat-Wideで必要なのはまずはrow scanを用いてブラウンを探し出し、カラムのエッジを取得する
- tall-narrowは1回rowスキャンをしただけでその中に関連性の情報が入っているので、何を求めているかがすぐ見つかる
- 行を分割できる
- hotspotのrowを別々にもつこともできる
- 並列でスキャンができる
- クエリの例として、友達の友達を見る際に、それぞれが1つの深さのインデックスを持つ場合に、flat-wideは8回の演算でできるが、tall-narrowだと4回で検索できる
Fine-Tuning Gravty
- Graphトラバーサルクエリの例として、ブラウンの友達のTOP5を出している例では、GraphStep、FilterStep, VertexStep, FilterStep, RangeStepの5つのステップを用いて検索している
- ブラウンの友達5人を名前の順番にピックアップする例
- incoming vert stepはGravityの名前を順番に出す
- Gravityは平行に名前をよむ。
HotSpotの回避
- rowのキーがどう作られているかで、リージョンスポットに悩む可能性がある
- 作られた順番でSrcVertexIdが作られた場合リージョンが偏る場合もある
- ストレージも足りない場合もある
- hotspotの問題を解決する方法として、pre spitingもしくはSalting rowを使うという方法がある
- Salting rowを使ってみたらパフォーマンスの問題が起こったので、LIMITを使った。しかしSaltingテーブルがドロップしてしまうかもしれなかった
- phoneixクライアントはリージョンスキャンは全てのスキャンをしてしまう事がある
- マージソートタスクはクエリーパフォーマンスを下げてしまうので別の方法を探した
- 考えた方法としてSaltingテーブルとPre-Splittingの両方を使う方法を編み出した
- Custom Salting + Pre-splittingの方法は、row key prefixを最初につかい、近い同期をまとめて確保することができるようになり、パフォーマンスが3倍よくなった
- グラフの検索が早くなったが、Secondary Indexが必要
- Hbaseはインデックスをサポートしていないのであたらしいものを使うことにした
- PhoneixのIndexCommiterは同期に作業して、障害回復をするツールを開発した
- GavtyのIndexCommitterフローについて
- Kafkaを使ってIndexerのコントロールを行うことにしたら、phoneixは非同期でインデックスを見ることができるようになり、rpcトラフィックのボリュームを下げることができるようになった
- Kafkaを実装した後、TPSが3倍になり、接続数が1/8になった、10ms以内でレスポンスができるようになった
障害への備え
- 緊急に対するポリシーとしては速く壊れてあとで修正するように設計されている
- filed requestをリプレイすることができるツールを作った
- 特定のランタイムの後にプロセスを移動させることができるようにした
- 自動に処理をやるように人力している
今後のプラン
- 現在単一のHbaseクラスタはシングルクラスをserveできるが、今後は複数のクラスタを統合できるようにしたいと考えている
- HBase Repositoryをストレージレイヤーで使えるようにして、Phoneixを使わずにHBaseを使えるようにしたい
- 今現在OLTPしかGravityは実行されていないが、今後はOLAPの機能も機能を加えたい
- コンピューティングAPIを実装してやろうとしている
- GravtyをOSS化するので、もっと詳細なデータを提供します
すべて英語のセッションだったのですが、専門用語がバンバン飛び交い、また翻訳が追いついていないくらい進行もとても早かったため、理解が追いつかず、ひたすらメモを殴り書く形になってしまいました…
もう一度見直してかろうじてモデルはなんとなくわかったような気もしますが、やっぱり全体的にこのセッションは難しすぎてよくわからなかったです。。。
資料を見ながら合わせて本メモを見てもらえると幸いです。
自分の勉強不足を実感したセッションでした。
View Comments
こんにちは gravtyスピーカーだったLee KyoungBokです。 非常に整理をよくしてくれましたね^^日本語ができなくて英語で伝えいたしました。 もう少し詳細な内容は、他の機会を通じて紹介します。 関心を持ってくださってありがとうございます。
お恥ずかしい文章ですいません。講演いただきありがとうございました。
また、機会がありましたらリベンジいたしますので、是非ご講演お願い致します。
Thanks for sharing. I read many of your blog posts, cool, your blog is very good.