Plesk Obsidianリリース記念!Plesk最大7カ月無料キャンペーン

2012/3/21

【実証】Apache CassandraでNoSQLに挑戦 後編

GMOクラウド株式会社の芦田です。前回の”【実証】Apache CassandraでNoSQLに挑戦 前編“に引き続き、Apache Cassandraの使い方を紹介します。今回はCassandraに対するデータの書き込みおよび読み出しの方法と、複数ノードでのクラスタの構成方法を解説します。

1 接続の確認

まず、前回インストールしたCassandraにコンソールから接続してみましょう。Cassandraにはコンソールベースのクライアントプログラム「cassandra-cli」が付属しています。cassandra-cliコマンドはbinディレクトリにあり、接続先ノードのホスト名(IPアドレス)とポート番号を指定して次のように実行します。
[root@kumolabo-cassandra ~]# /usr/local/cassandra/bin/cassandra-cli -host xxx.xxx.xxx.xxx -port 9160
Connected to: “Test Cluster” on 172.16.0.66/9160
Welcome to Cassandra CLI version 1.0.6
Type ‘help;’ or ‘?’ for help.
Type ‘quit;’ or ‘exit;’ to quit.
[default@unknown]
プロンプト1.1
このように「[default@unknown]」と出たら、接続に成功してCassandraのコンソールに入った状態ということで、データベースを管理する各種コマンドが使えます。終了するコマンドは「quit;」または「exit;」です。
nodetoolというコマンドを使えば、ノードの状態を調べることができます。次のようにホストを指定し、ringオプションを付けてnodetoolコマンドを実行してみましょう。現在クラスタを構成しているノード(今はまだ1ノード)が一覧表示されます。
[root@kumolabo-cassandra bin]# /usr/local/cassandra/nodetool -h xxx.xxx.xxx.xxx ring
Address DC Rack Status State Load Owns Token

xxx.xxx.xxx.xxx datacenter1 rack1 Up Normal 192.57 KB 100.00%
157601645397734763130615192721786119187
プロンプト1.2
cassandra.yamlのrcp_addressの項目と、ファイアウォールの設定が正しければ、外部のホスト(本稿の例ではkumolabo-test)からも同様に接続できるはずです。ただし、当然ながらクライアント側にもcassandra-cliやnodetoolのプログラムが必要です。

2 Cassandraのデータモデル

Cassandraのデータ構造は、「キースペース」、「カラムファミリー」、「キー」、「スーパーカラム」、「カラム」の5つから構成され ます。この5つ、または「スーパーカラム」を除いた4つをセットにしたものを、データを特定するためのキーとして扱います。つまり、この4つないし5つがわかれば、必ず1つのデータを特定できるということです。

「キースペース」はRDBでいうところのデータベースにあたるもので、一般的には1つのアプリケーションにつき1つ用意します。「カラムファミリー」はカラムまたはスーパーカラムの集まりです。RDBのテーブルに該当します。「キー」は横方向のデータの集合を扱うもので、RDBの行のようなものです。「スーパーカラム」は複数のカラムを1つのまとまりとして扱う場合に使用します。「カラム」はデータの最小単位で、実際にデータを特定するためのものになります。

3 データの書き込みと読み出し

データを格納するには、まずキースペースとカラムファミリーが必要です。キースペースの作成はcreate keyspaceコマンドを使って行います。「Keyspace1」という名前のキースペースを作る場合には次のようになります。
[default@unknown] create keyspace Keyspace1;
プロンプト3.1
キースペースが作れたら、useコマンドを使って現在のキースペースを作成したもの(Keyspace1)に変更します。
[default@unknown] use Keyspace1;
プロンプト3.2
カラムファミリーの作成には、create column familyコマンドを使います。SQLのcreate tableに相当するものですが、あらかじめカラム名を指定しておく必要はありません。次の例は、「address」という名前のカラムファミリーを作成 するものです。4行で1つのコマンドですが、「;」を入力するまでは改行しても実行されません。ここでは文字コードとしてUTF8を使うように指定しています。
[default@Keyspace1] create column family address
… WITH comparator = UTF8Type
… AND key_validation_class=UTF8Type

… AND default_validation_class = UTF8Type;

プロンプト3.3
データの書き込みはsetコマンドを使って、「キー=値(データ)」の形式で行います。キーは[キースペース]+[カラムファミリー]+ [キー]+[カラム]のセット、または[キースペース]+[カラムファミリー]+[キー]+[スーパーカラム]+[カラム]のセットで、文法としては「カラムファミリー[キー][カラム]」のように記述します。次の例はaddressファミリーに対していくつかのデータの書き込んでみるものです。
[default@Keyspace1] set address['gmo']['fullname']=’GMO TARO’;
[default@Keyspace1] set address['gmo']['email']=’gmo@example.com’;
[default@Keyspace1] set address['cloud']['fullname']=’CLOUD JIRO’;
[default@Keyspace1] set address['cloud']['email']=’cloud@example.com’;
[default@Keyspace1] set address['kumolabo']['fullname']=’KUMOLABO HANAKO’;
[default@Keyspace1] set address['kumolabo']['email']=’kumolabo1@example.com’;

プロンプト3.4
データを読み出す場合はgetコマンドを使います。次のようにgetコマンドにカラムまで指定して渡せば、対象のデータが取得できます。
[default@Keyspace1] get address['gmo']['email']; => (column=email, value=gmo@example.com, timestamp=1324475461286000)

プロンプト3.5
カラムまですべて指定しなくても、キーまでを特定すればそのキーに含まれるカラムのデータの一覧が取得できます。
[default@Keyspace1] get address['gmo'];
=> (column=email, value=gmo@example.com,
timestamp=1324475461286000)
=> (column=fullname, value=GMO TARO, timestamp=1324475429966000)

プロンプト3.6
カラムファミリーの全データを取得したい場合には、次のようにlistコマンドを使います。
[default@Keyspace1] list address;
Using default limit of 100
——————-
RowKey: kumolabo
=> (column=email, value=kumolabo1@example.com,
timestamp=1324475616390000)
=> (column=fullname, value=KUMOLABO HANAKO, timestamp=1324475601457000)
——————-
RowKey: gmo
=> (column=email, value=gmo@example.com,
timestamp=1324475461286000)
=> (column=fullname, value=GMO TARO, timestamp=1324475429966000)
——————-
RowKey: cloud
=> (column=email, value=cloud@example.com,
timestamp=1324475560431000)
=> (column=fullname, value=CLOUD JIRO, timestamp=1324475542471000)
プロンプト3.7

4 複数ノードでクラスタを構成する

GMOクラウド Publicであれば仮想サーバーを複数立てられるので、せっかくですから複数ノードでクラスタを構成してみましょう。今回は3つのノードで、ノード1はこれまで使ってきたもので、ノード2とノード3も同じ構成で仮想サーバーを構築します。すべてローカルネットワーク上に構築します。 cassandra.yamlの設定は、それぞれ次のようなになります(IPは各自の環境に読み替えてください)。
ノード1(IP: xxx.xxx.xxx.1):
• listen_address: xxx.xxx.xxx.1
• rpc_address: xxx.xxx.xxx.1
• seeds: xxx.xxx.xxx.1
ノード2(IP: xxx.xxx.xxx.2):
• listen_address: xxx.xxx.xxx.2
• rpc_address: xxx.xxx.xxx.2
• seeds: xxx.xxx.xxx.1
ノード3(IP: xxx.xxx.xxx.3):
• listen_address: xxx.xxx.xxx.3
• rpc_address: xxx.xxx.xxx.3
• seeds: xxx.xxx.xxx.1

クラスタに参加するために必要なseedとしてノード1のアドレスを指定していることがポイントです。したがって、まずはノード1を最初に起 動する必要があります。ノード1のCassandraが起動したら、ノード2とノード3のそれぞれでCassandraを立ち上げます(順番はどちらでも 構いません)。無事にseedを見つけることができればクラスタに参加してデータの同期が行われます。
3ノードとも起動できたらnodetoolコマンドでノードの状態を見てみましょう。対象はどのノードでも構いません。次のように3つのノードがクラスタを構成していることが確認できます。
[takasyou@kumolabo-test bin]$ ./nodetool -h xxx.xxx.xxx.1 ring
Address DC Rack Status State Load Owns Token

157601645397734763130615192721786119187

xxx.xxx.xxx.3 datacenter1 rack1 Up Normal 172.39 KB 25.00%
29995757802382839331849714934873039891
xxx.xxx.xxx.2 datacenter1 rack1 Up Normal 190.96 KB 25.00%
72531053667500147264771540863844066323
xxx.xxx.xxx.1 datacenter1 rack1 Up Normal 188.17 KB 50.00%
157601645397734763130615192721786119187

プロンプト4.2
ノード2(またはノード3)に接続して、addressファミリーのデータにアクセスしてみましょう。次のように、先ほどノード1に登録したものが取得できるはずです。
[root@kumolabo-test bin]# ./cassandra-cli -host xxx.xxx.xxx.2 -port 9160
[default@unknown] use Keyspace1;
[default@Keyspace1] list address;
Using default limit of 100
——————-
RowKey: kumolabo
=> (column=email, value=kumolabo1@example.com, timestamp=1324475616390000)
=> (column=fullname, value=KUMOLABO HANAKO, timestamp=1324475601457000)
——————-
RowKey: gmo
=> (column=email, value=gmo@example.com, timestamp=1324475461286000)
=> (column=fullname, value=GMO TARO, timestamp=1324475429966000)
——————-
RowKey: cloud
=> (column=email, value=cloud@example.com, timestamp=1324475560431000)
=> (column=fullname, value=CLOUD JIRO, timestamp=1324475542471000)

プロンプト4.3
このように、複数ノードでクラスタを構成しても、使い方は単一ノードの場合と変わりません。RDBとは根本的なデータ構造が違うので最初は戸惑うかもしれませんが、クラウドのメリットを最大限に生かすために、ぜひNoSQLを使いこなしましょう。


コラム一覧へ