blog

[DB] [GraphDB] [OrientDB]
今さらながらのグラフDB事始め

はじめに

この記事は、foodison advent calendar 2015 の3日目の記事です。

ようやく入社して2ヶ月が経過した金田です。 僕の回では、OrientDB をご紹介したいと思います。

OrientDBとは

OrientDBは、U.K.在住のイタリア人、Luca Garulli氏が開発したNoSQLなデータベース管理システムです。 主な特徴としては、

  • グラフデータベースかつ、ドキュメントデータベースである
  • オブジェクトデータベース上に実装されている
  • スキーマフル、スキーマレス、その混成が可能
  • それでいて、SQL風の問い合わせ言語をもつ
  • グラフデータをハンドリングするインタフェースのデファクトスタンダードである、TinkerPop Gremlinをサポート
  • マルチマスタ分散データベース機能をもつ

といったところでしょうか。

ドキュメントデータベース

ドキュメントデータベースとは、いわゆるKey-Valueストアと言われる、スキーマレスで大量のデータを格納、検索できるDBMSのことを言います。MongoDB がその代表格。タイムスタンプをキーに、イベントログを蓄積したり、キーを渡してデータを受け取る、という巨大なハッシュとして利用されるシーンが多いようです。

ウェブからデータをかき集めてくるクローラーを作ったりする場合、先方のサーバに迷惑をかけないようにしたり、そもそもアクセス回数に制限があったりすることがよくあり、可能な限り、アクセス機会を有効利用しようとすると、どうしても、一度アクセスして取得したコンテンツは、その場で必要なデータだけ抜き出してあとは捨てるのではなく、取得したままの形で保存しておいて、何度も再利用しようとしたくなります。そういった場合に、HTTPのレスポンスデータをそのままごっそり、ドキュメントデータベースにリクエストパラメータのセットと合わせて格納しておく、といったことが簡単にできます。 もちろん、mysql等のRDBでも簡単にできますが、ドキュメントデータベースの場合いちいちスキーマを用意して、create tableして、という煩わしさがありません。 これまでだと、ファイル名をつけて、ファイルとして保存しておくようなユースケースで、ファイルハンドリングの煩わしさを解消する目的で、キーを付加して、ドキュメントDBに格納しておく、という使い方がいいように個人的には思います。

この辺は、中身を解析して、構造化したうえでちゃんとDBに格納しておくのか、解析、構造化は後回しでとりあえず取っておくのか、といった使い方次第でどちらを使うか、という判断になるかと思います。

グラフデータベース

ノード(頂点)とエッジ(辺)により、大量のオブジェクトとそれらの関係性を保持するのに適したデータモデルによるデータベースです。通常のRDBでは、Joinが大量に発生し、現実的でないようなデータや、ノード間の最短経路を探索したり、多くの構成部品からなるプロダクトがあった場合に、そのような包含関係を管理したり、といった用途に用いられることが多いようです。 実際に使われている身近な例でいうと、Facebookや、LinkedIn といったSNSにおける、人間関係(友人関係等)を保持するのに(独自の)グラフデータベースが用いられているようです。

アマゾンの商品データベースをクロールしたことがある人ならご存知だと思いますが、アマゾンをはじめとするECサイトの商品データは、いくつもの階層にわけられたカテゴリに分類され管理されています。そのようなツリー構造、階層構造を管理する際にグラフデータベースが用いられることが多いです。

オブジェクトDBが基盤

これはつまり、ドキュメントDBとしてのAPI、グラフDBとしてのAPI が用意されているだけでなく、さらに低レイヤーのオブジェクトDBとしてのAPIが用意されている、ということです。KVSや、グラフだけでなく、独自のオブジェクトモデルを格納するデータベースとしても用いることが可能です。実際筆者は1997年ごろに初めてオブジェクトDBを使った開発を行っていましたが、その際は、巨大なネットワークの構造を維持管理するためのNW管理システムとして、網構成を管理するのに利用していました。

スキーマフル

通常のRDBと同じように、予めスキーマを定義しておいて、そのスキーマに基づいたデータを格納する、という使い方が可能です。

スキーマレス

一方で、ドキュメントDB的な、スキーマを定義せずに、データを格納することができます。スキーマ定義を含む「データを格納するための準備」を極力減らし、気軽にデータを格納できるようになっています。

混成型

スキーマフル+スキーマレスの混成型が可能ということは、すなわち、あとからスキーマに定義していないデータ構造をスキーマを更新させることなく、データベースに格納することが可能、ということです。

SQL風問い合わせ言語

格納された、オブジェクト等を検索するための言語として、SQLを独自に拡張した、問い合わせ言語が用意されています。中には、見慣れない表現もあります(独自拡張部分)が、SQLを使い慣れた方にとっては、とっつきやすい、またはデータ構造等が理解しやすいのではないでしょうか。

Gremlinサポート

グラフ構造のデータをハンドリングするための汎用インタフェースとして、様々なライブラリがApache TinkerPopで開発が進められています。そのTinkerPopプロジェクトでの成果物である、Gremlin は、グラフデータをハンドリングするためのDSL(Domain Specific Language)です。

OrientDBでは、このGremlinが標準で同梱されており、すぐに利用することができます。なお、Gremlinは、同様のグラフDBであるNeo4jでも利用することができますので、OrientDBに限らず、グラフ構造をごにょごにょしたい、ということであれば覚えておいて損はないです。

マルチマスター分散データベース

分散キーバリューストアの代表であるHBaseでは、分散処理を行うためのコーディネータとしてApache Zookeeperが組み込まれています。

OrientDBでも同様に、Javaベースのキャッシュ、クラスタリング、データ配信ソリューションを提供するHazelcastというミドルウェアが組み込まれています。OrientDBでは、これを利用して、マルチマスター分散DBの仕組みが構成されています。通常、DBMSにおける分散コーディネータは、DBMSの外部に位置し、複数のDBMSインスタンスを相手にコーディネートする立ち位置になります。これに対し、OrientDBではDBMS内部にすでに組み込まれているので、煩わしい設定なしで、マルチマスター分散DBサーバを構築することができます。

また、こういったオプション的な機能が、Enterprise版(有償ライセンス)ではなく、Community版(オープンソース版)に組み込まれていることは使う側としても大変うれしいところだと思います。

環境構築

では、試しにサーバを動かすところまで構築してみましょう。なお、Ubuntu環境での構築を例として挙げます。OrientDB自体はJavaで書かれていますので、ほぼどんな環境でも動作すると思われますので、適宜読み替えてください。

Javaのインストール

まず、Javaのランタイム環境を用意します。

% sudo echo oracle-java7-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections
% sudo apt-get install -y software-properties-common
% sudo add-apt-repository -y ppa:webupd8team/java
% sudo apt-get update
% sudo apt-get install -y oracle-java8-installer
% sudo apt-get install -y oracle-java8-set-default

OrientDB のインストール

  • http://orientdb.com/download/ にアクセスします。
  • インストール先のOSに合わせて、アイコンをクリックすると、ダウンロードが開始されます。
    • orientdb-community-2.1.6.tar.gz というファイルがダウンロードされた、とします。
  • インストールする先へファイルを展開します。(以下は、筆者の例です。)
% cd /usr/local/
% mv $HOME/Downloads/orientdb-community-2.1.6.tar.gz .
% sudo tar zxvf orientdb-community-2.1.6.tar.gz
% cd orientdb-community-2.1.6
% ls
benchmarks bin config databases history.txt lib license.txt log plugins readme.txt www

これで、インストールは完了です。

OrientDB サーバの起動

% cd bin/
% sudo ./server.sh
           .                                          
          .`        `                                 
          ,      `:.                                  
         `,`    ,:`                                   
         .,.   :,,                                    
         .,,  ,,,                                     
    .    .,.:::::  ````                                 :::::::::     :::::::::   
    ,`   .::,,,,::.,,,,,,`;;                      .:    ::::::::::    :::    :::  
    `,.  ::,,,,,,,:.,,.`  `                       .:    :::      :::  :::     ::: 
     ,,:,:,,,,,,,,::.   `        `         ``     .:    :::      :::  :::     ::: 
      ,,:.,,,,,,,,,: `::, ,,   ::,::`   : :,::`  ::::   :::      :::  :::    :::  
       ,:,,,,,,,,,,::,:   ,,  :.    :   ::    :   .:    :::      :::  :::::::     
        :,,,,,,,,,,:,::   ,,  :      :  :     :   .:    :::      :::  :::::::::   
  `     :,,,,,,,,,,:,::,  ,, .::::::::  :     :   .:    :::      :::  :::     ::: 
  `,...,,:,,,,,,,,,: .:,. ,, ,,         :     :   .:    :::      :::  :::     ::: 
    .,,,,::,,,,,,,:  `: , ,,  :     `   :     :   .:    :::      :::  :::     ::: 
      ...,::,,,,::.. `:  .,,  :,    :   :     :   .:    :::::::::::   :::     ::: 
           ,::::,,,. `:   ,,   :::::    :     :   .:    :::::::::     ::::::::::  
           ,,:` `,,.                                  
          ,,,    .,`                                  
         ,,.     `,                                          GRAPH DATABASE  
       ``        `.                                                          
                 ``                                          orientdb.com
                 `                                    

2015-12-03 17:03:21:128 INFO  OrientDB auto-config DISKCACHE=5,441MB (heap=494MB os=7,984MB disk=102,805MB) [orientechnologies]
2015-12-03 17:03:21:351 INFO  Loading configuration from: /usr/local/orientdb-community-2.1.6/config/orientdb-server-config.xml... [OServerConfigurationLoaderXml]
2015-12-03 17:03:21:974 INFO  OrientDB Server v2.1.6 (build 2.1.x@r; 2015-11-24 02:07:42+0000) is starting up... [OServer]
2015-12-03 17:03:21:977 INFO  Databases directory: /usr/local/orientdb-community-2.1.6/databases [OServer]
2015-12-03 17:03:22:050 INFO  Listening binary connections on 0.0.0.0:2424 (protocol v.32, socket=default) [OServerNetworkListener]
2015-12-03 17:03:22:294 INFO  Listening http connections on 0.0.0.0:2480 (protocol v.10, socket=default) [OServerNetworkListener]

+---------------------------------------------------------------+
|                WARNING: FIRST RUN CONFIGURATION               |
+---------------------------------------------------------------+
| This is the first time the server is running. Please type a   |
| password of your choice for the 'root' user or leave it blank |
| to auto-generate it.                                          |
|                                                               |
| To avoid this message set the environment variable or JVM     |
| setting ORIENTDB_ROOT_PASSWORD to the root password to use.   |
+---------------------------------------------------------------+

Root password [BLANK=auto generate it]: 

server.sh という起動スクリプトが用意されていますので、直接これを実行します。

実行すると、コンソール上にそのままスプラッシュのアスキーアートと、サーバの動作ログが表示されます。初めてサーバを起動した時は、管理者権限のパスワードの入力を求められます。ブランクのままリターンを入力すると、ランダムにパスワードが設定されます。設定されたパスワードは、$ORIENTDB_ROOT/config/orientdb-server-config.xml の最後尾付近に、

<users>
  <user resources="*" password="DF29EDC0D9FFD429C560DB64B46DC908864A3EB02587E67D809CFFAE826A5F03" name="root"/>
  <user resources="connect,server.listDatabases,server.dblist" password="guest" name="guest"/>
</users>

といった感じで記憶されています。

これでサーバの起動が完了しました。 では、グラフを登録してみましょうか、と言いたいところですが、残念ながら紙面(?)が尽きてしまいました。

今宵はここまでに致しとうございます。

では、また会おう。ぐひゃひゃひゃひゃ。

おわりに

foodison のミッションは「世界の食をもっと楽しく」です。
このミッションに共感するようなエンジニアの方は、是非一度遊びに来てください!
今月から勝どきのオフィスに移転して勤務が始まっています。
採用関連に関してもっと知りたい方は こちらの wantedly を参照してください。