2016.07.04

NoSQLデータベース Riak


riak

次世代システム研究室の データストア 好きの Y.I. です。

今回は個人的に注目している Basho Technologies, Inc. の分散 NoSQL データベース Riak についてご紹介します。

■ Riak について


現在、 Riak(シリーズと言えばいいのでしょうか?) には3つのプロダクトが展開されています。

・キーバリューストアの Riak KV
・2015年に公開された時系列データ向けの Riak TS
・AWS S3 APIと互換性があるオブジェクトストレージの Riak S2

各プロダクトは全て分散型となっておりノードの追加を行うことでリニアにキャパシティや性能があがります。言語はErlang言語で作られていて並行処理や対障害性に優れています。またOSSとしても提供されています。


■ Riak KV の特徴


  • Amazon Dynamo 論文をベースに設計された分散 KVS
  • データ構造は バケット(DBテーブルに該当)内に Key/Value データを持つ
  • 自動クラスタリング
    • 3コマンドによるノード追加や削除が可能
  • マスターレスでありデータの保存ノードをユーザが知る必要がない
  • データの自動リバランシング
    • ノードを追加時に自動でデータを再配置する
  • 故障ノードの自動回避
    • 他のノードが問い合わせを受け持つ
  • REST API や Protocol Buffers で操作可能
  • 類似プロダクトは AWS DynamoDB や Apache Cassandra など

■ Riak KV デモ


今回は、Riak KV およびクラスターの構築からデータのCRUDやノードの追加方法をご紹介します。

▼ Riak 構築


basho 社が提供してくれている docker イメージ basho/riak-kv を利用して docker-compose コマンドで環境構築してみましょう。手順通りに実行すると5ノード起動します。その後5ノードを連携して Riak クラスターを構築してみましょう。前提として docker がインストールされていて起動しているものとします。

1. ワーキングディレクトリ名を riak とする


$ mkdir riak && cd riak


2. docker-compose.yml ファイルを作成する

ファイル内容は以下のとおりです。
version: "2"
services:
 coordinator:
  image: basho/riak-kv
  ports:
   - "8087:8087"
   - "8098:8098"
  environment:
   - CLUSTER_NAME=${CLUSTER_NAME}
  labels:
   - "com.basho.riak.cluster.name=${CLUSTER_NAME}"
  volumes:
   - schemas:/etc/riak/schemas
 member:
  image: basho/riak-kv
  ports:
   - "8087"
   - "8098"
  labels:
   - "com.basho.riak.cluster.name=${CLUSTER_NAME}"
  links:
   - coordinator
  depends_on:
   - coordinator
  environment:
   - CLUSTER_NAME=${CLUSTER_NAME}
   - COORDINATOR_NODE=coordinator

volumes:
 schemas:
  external: false

3. ノードの起動

Riak クラスターの中心となるノードとして coordinator というコンテナ名で起動します。

$ export CLUSTER_NAME=test
$ docker-compose up -d coordinator


実行結果
$ docker-compose up -d coordinator
Creating network "riak_default" with the default driver
Creating volume "riak_schemas" with default driver
Pulling coordinator (basho/riak-kv:latest)...
latest: Pulling from basho/riak-kv
56eb14001ceb: Pull complete
7ff49c327d83: Pull complete
6e532f87f96d: Pull complete
3ce63537e70c: Pull complete
bcb64e6fe4d2: Pull complete
953ae312fb45: Pull complete
26a5c5d13a6a: Pull complete
034cbe32736f: Pull complete
9aa545455dfb: Pull complete
b62e0f8fc537: Pull complete
2844391110be: Pull complete
9bfe26470456: Pull complete
4087327bd3ad: Pull complete
00f156c788f6: Pull complete
71dc455a720a: Pull complete
34ab5361e0c2: Pull complete
9333bafa4395: Pull complete
02cddc69f979: Pull complete
c2da8c537a8c: Pull complete
d74d44961f7a: Pull complete
63c14d807a22: Pull complete
Digest: sha256:3f1ef68177add3884d0e8ba000954c7924e5e0d8f82e0751b2583cda57403581
Status: Downloaded newer image for basho/riak-kv:latest
Creating riak_coordinator_1

4. ノードの起動

Riak クラスターに参加するノードとして member というコンテナ名で4ノード起動します。

$ docker-compose scale member=4

実行結果
$ docker-compose scale member=4
Creating and starting 1 ... done
Creating and starting 2 ... done
Creating and starting 3 ... done
Creating and starting 4 ... done

起動中の docker コンテナ一覧
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                              NAMES
dfaaa4309c48        basho/riak-kv       "/usr/lib/riak/riak-c"   About a minute ago   Up About a minute   0.0.0.0:32775->8087/tcp, 0.0.0.0:32774->8098/tcp   riak_member_3
06981c5a0a6a        basho/riak-kv       "/usr/lib/riak/riak-c"   About a minute ago   Up About a minute   0.0.0.0:32773->8087/tcp, 0.0.0.0:32772->8098/tcp   riak_member_2
1ec94058d0af        basho/riak-kv       "/usr/lib/riak/riak-c"   About a minute ago   Up About a minute   0.0.0.0:32771->8087/tcp, 0.0.0.0:32770->8098/tcp   riak_member_1
42fdd34b3b0b        basho/riak-kv       "/usr/lib/riak/riak-c"   About a minute ago   Up About a minute   0.0.0.0:32769->8087/tcp, 0.0.0.0:32768->8098/tcp   riak_member_4
76ac714a89b3        basho/riak-kv       "/usr/lib/riak/riak-c"   52 minutes ago       Up 8 minutes        0.0.0.0:8087->8087/tcp, 0.0.0.0:8098->8098/tcp     riak_coordinator_1

 ※ NAMES を用いてコンテナにログインします。

以上で、 docker image を使った Riak の起動まで完了です。
以降で、 Riak クラスターを構築します。


▼ Riak クラスターの構築


起動した4つの member コンテナ上の Raik を Coodinator コンテナ上の Riak と連携してクラスタを構築します。各ノードで3コマンドを実行するとクラスタ構築が完了します。

まず docker コンテナへログインしましょう
riak_member_1 コンテナへログイン


$ docker exec -it riak_member_1 bash

※上記 コンテナ一覧の NAMES を指定します


1. コマンド1 join



$ riak-admin cluster join riak@XXX.XX.X.2

※ XXX.XX.X.2 の箇所は coordinator コンテナのIPアドレスを指定します。
    coordinatorノードにログインして ifconfig で確認できます。


2. コマンド2 plan



$ riak-admin cluster plan


3. コマンド3 commit


$ riak-admin commit


以上で完了です。 1ノードが Riak クラスタに参加できました。
以降、他の member コンテナでも同様に操作します。


$ docker exec -it riak_member_2 bash
...
$ docker exec -it riak_member_3 bash
...
$ docker exec -it riak_member_4 bash
...



4. Riak クラスタ状況の確認


5ノードで構成された Riak クラスタを確認してみましょう。

# riak-admin cluster status


実行結果
---- Cluster Status ----
Ring ready: true

+---------------------+------+-------+-----+-------+
|        node         |status| avail |ring |pending|
+---------------------+------+-------+-----+-------+
| (C) riak@XXX.XX.X.2 |valid |  up   | 18.8|  --   |
|     riak@XXX.XX.X.3 |valid |  up   | 18.8|  --   |
|     riak@XXX.XX.X.4 |valid |  up   | 18.8|  --   |
|     riak@XXX.XX.X.5 |valid |  up   | 18.8|  --   |
|     riak@XXX.XX.X.6 |valid |  up   | 25.0|  --   |
+---------------------+------+-------+-----+-------+
5ノードの Raik クラスタが稼働していることを確認できます。


▼ データ操作

データの登録と参照と削除を行います。まずDBでいうテーブルに該当するバケットを定義します。すべて REST API で操作可能です。

バケットの作成

バケット名 :「hoge」、データ複製数 :「3」で作成してみます。


$ curl -X PUT -H "Content-Type: application/json" -d '{"props":{"n_val":3}}' http://XXX.XX.X.100:8098/buckets/hoge/props

※ http://XXX.XX.X.100 は docker-machine ls で表示されるIPアドレスを指定します。


バケット hoge の状態を確認
curl http://XXX.XX.X.100:8098/buckets/hoge/props | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   461  100   461    0     0   225k      0 --:--:-- --:--:-- --:--:--  450k
{
  "props": {
    "allow_mult": false,
    "basic_quorum": false,
    "big_vclock": 50,
    "chash_keyfun": {
      "mod": "riak_core_util",
      "fun": "chash_std_keyfun"
    },
    "dvv_enabled": false,
    "dw": "quorum",
    "last_write_wins": false,
    "linkfun": {
      "mod": "riak_kv_wm_link_walker",
      "fun": "mapreduce_linkfun"
    },
    "n_val": 3,
    "name": "hoge",
    "notfound_ok": true,
    "old_vclock": 86400,
    "postcommit": [],
    "pr": 0,
    "precommit": [],
    "pw": 0,
    "r": "quorum",
    "rw": "quorum",
    "small_vclock": 50,
    "w": "quorum",
    "write_once": false,
    "young_vclock": 20
  }
}

※ "n_val": 3 や "name": "hoge" を確認できます。


データ登録

バケット「hoge」 に キー「hoge」 バリュー「this is value」 を登録してみます(=DBでいうレコードの INSERT )


$ curl -X PUT -H "Content-Type: text/plain" -d "this is value" http://XXX.XX.XX.100:8098/buckets/hoge/keys/fuga


データ参照

バケット「hoge」 の キー「hoge」 のバリューを表示(=DBでいうレコードの SELECT )


$ curl -X GET http://XXX.XX.XX.100:8098/buckets/hoge/keys/fuga


実行結果
http://XXX.XX.X.100:8098/buckets/hoge/keys/fuga
this is value

データ削除

バケット「hoge」 の キー「hoge」 を削除(=DBでいうレコードの DELETE )


$ curl -X DELETE http://XXX.XX.X.100:8098/buckets/hoge/keys/fuga



画像データ登録

Riak KVはバイナリデータの登録も可能です。画像を登録してみましょう。

カレントディレクトリの riak.png 画像をバケット「hoge」にキー「fugafuga」で登録


$ curl -X PUT -H "Content-Type: image/png" -T "./riak.png" http://XXX.XX.X.100:8098/buckets/hoge/keys/fugafuga


画像データ参照

ブラウザで下記URLを参照すると画像を確認できます。

http://XXX.XX.XX.100:8098/buckets/hoge/keys/fugafuga


■ インプレッション


運用が楽

何よりも運用が楽というのが一番の魅力ではないでしょうか。各ノードで3コマンドを実行するだけでノードを追加や削除できます。(最初に実行した際にあまりのお手軽さに驚きました)ハードウエア障害などでノードがダウンしても他のノードが自動で応答を代替してくれて継続稼働できます。そのためノード復旧の為に深夜対応は不要となり、翌営業日にノード復旧(追加)させれば良い運用体制となります。またノード追加時は自動でデータのリバランシングが行われるのでアプリケーションを変更する必要もありません。

REST API

REST APIを用いて簡単に操作が可能です。各プログラム言語向けに接続ミドルウエアが提供されていなくても、REST APIでアクセス可能です。


■ 最後に


今回は Riak の特徴と docker image を用いたクラスタの構築と簡単な操作までを紹介させてもらいました。紹介しきれなかった Riak KV の機能や Riak TS についても次回以降で紹介させてもらう予定です。


■ 参考文献



次世代システム研究室では、グループ全体のインテグレーションを支援してくれるアーキテクトを募集しています。アプリケーション開発の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。

皆さんのご応募をお待ちしています。