【Node.js】cassandra-nodeを入れてみた

今つくってるiOSアプリであるクラウドにデータを貯めたいと思い, AWS EC2を始めました。
とりあえずやってみたのでメモっときます。Nodejsはいいとして, 何故Cassandraなのか?

それは単なる興味です。

Node.js でサンプル動かして, cassandra-node をインストールするまでの内容です。
インフラに慣れてる人は役にたてない初歩的な記事ですのであしからず(´▽`)ノ

Cassandra

構成は, Linux (AMI), Node.js 0.8.14, Cassandra 1.1.7です。

Cassandraは元々facebookが大量のランダムRead/Writeから生まれるビックデータを扱うという目的で作られたようです。
設計思想から考えると, ビッグデータのリアルタイム分析でよく使われているみたいです。

CAP定理によると, 以下の3つのうち2つしか獲得できないという説明をよく見ます。

  • Consistency : 一貫性:単一の最新データを常に保持する。
  • Availability : 可用性:データ更新時のに高い可用性
  • Partition Tolerance : 耐性:ネットワーク分割に対する耐性

MySQLなど多くのRDBはACに分類されます。CassandraはAPに特化してますが一貫性(C)と遅延のトレードオフを調整できること(レプリケーションファクター)が特徴のようです。
また, NoSQLですが単純なKey/Valueとは違い, 深さのあるデータモデルがつくれるらしいです。(多次元ハッシュテーブル)

この辺の詳細は別途, ググってください。

Cassandraのクライアントツールは様々あります。コンソールから検索をかけるCLIとかRPCフレームワークの Thrift(C++, C#, Java, OCaml, Perl, Python, PHP, Ruby対応)がよくひっかかります。
今回はNodejsからCassandraにアクセスするので, Cassandra-nodeを使うという内容の話です。

AWS EC2

AWS EC2は必要な分だけ利用できるクラウドサーバです。スケールアップ (スペックアップ)する時はインスタンスを強化, スケールアウト(台数増加)する時はAMI (マシンイメージ)を複製します。

EC2のインスタンスを起動したらNodejsのサンプルを走らせるためにport3000を使うので, 先に空けておきます。
GlobalIPを建物に例えるとportは部屋にあたります。クライアントはportを指定してリクエストを送信します。
1024より小さい数字のportは Well Known Portと呼ばれます。

セキュリティグループ設定

セキュリティグループ設定は以下の通りです。

EC2 の管理画面で左側メニュー -> NETWORK & SECURITY -> Security Groups -> 使用しているセキュリティグループを選択 -> Inbound タブをクリック -> custom TCP PortのPortRangeで3000を指定 -> Add Rule -> Apply Rule Changes で完了です。

SSHでログイン

AWSでEC2インスタンスを作成して EIP (固定IP)を取得して紐付けます。
作成時に xxx.pem (BASE64でエンコードされたセキュリティ証明書)をダウンロードしてローカルに配置します。
下記のようにログインします。


ssh -i xxx.pem ec2-user@xxx

最初はpemファイルでログインしますが次回以降はsshで入れるようにしときます。
EC2インスタンスへのアクセスは公開鍵暗号方式です。この秘密鍵はなくさないように注意してください。


$ chmod 400 ***.pem
$ ssh -i airkey.pem ec2-user@ec2xxx.ap-northeast-1.compute.amazonaws.com

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2012.09-release-notes/

fisというユーザを追加してroot権限を追加し, sudoersを編集します。


# vim /etc/sudoers

scpでuploadします。


$ scp -i  ***.pem ~/.ssh/id_rsa.pub ec2-user@ec2xxx.ap-northeast-1.compute.amazonaws.com:/home/ec2-user/
id_rsa.pub
100%  417     0.4KB/s   00:00    

sshディレクトリに移動しときます。


$ ls
id_rsa.pub
$ mkdir /home/fis/.ssh
$ sudo mv id_rsa.pub /home/fis/.ssh/authorized_keys
$ sudo chown fis /home/fis/.ssh/authorized_keys
$ sudo chgrp fis /home/fis/.ssh/authorized_keys
$ sudo chmod 600 /home/fis/.ssh/authorized_keys
$ sudo chmod 700 /home/fis/.ssh

試しにfisでsshログインします。


$ ssh fis@ec2xxx.ap-northeast-1.compute.amazonaws.com

ログインはスクリプト化しておくと便利です。

Nodejs環境構築

Nodejs は Google の V8エンジンをベースにしたイベント駆動型I/O環境です。


$ sudo yum install git gcc-c++ make openssl-devel
$ git clone git://github.com/creationix/nvm.git ~/.nvm
Now using node v0.8.14

パッケージマネージャからのインストールもできます。


# on mac
$ sudo port install nodejs
# on centos
$ sudo yum install nodejs
# on debian
$ sudo apt-get install nodejs

HelloWorld を表示する httpサーバアプリを作成します。


$ vim sample_ec2.js

以下のコードを書きます。


var http = require('http');// httpモジュールの要求

http.createServer(function (request, response) {
   response.writeHead(200, {'Content-Type': 'text/plain'});
   response.end('Hello World\n');
}).listen(3000);

port3000を指定してブラウザでアクセスしてみます。


https://ec2xxx.ap-northeast-1.compute.amazonaws.com:3000/

初めの一歩はできました。

NodejsにはModuleが数多くあります。Expressは URLディスパッチャ, テンプレートエンジン, セッション管理機能, 静的ファイルの配信が行えます。

ec2 にログインして.bash_profileに以下を書き込みます。


$ source ~/.node/nvm.sh
$ nvm use v0.8.14

Cassandraをインストール

cassandraはJVM上で動くのでJDKをインストールします。JDK6がありましたが新しいJDK7を入れました。


$ sudo yum install java-1.7.0-openjdk
Loaded plugins: priorities, security, update-motd, upgrade-helper
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package java-1.7.0-openjdk.x86_64 1:1.7.0.9-2.3.3.13.amzn1 will be installed
--> Finished Dependency Resolution

jre-1.7.0を適用させます。


$ sudo alternatives --config java

2 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java

wgetで cassandraバイナリをダウンロードします。


$ sudo wget https://ftp.kddilabs.jp/infosystems/apache/cassandra/1.1.7/apache-cassandra-1.1.7-bin.tar.gz
// 展開
$ tar -xvzf apache-cassandra-1.1.7-bin.tar.gz 
// 後片付け
$ rm apache-cassandra-1.1.7-bin.tar.gz
// インストール
$ sudo ln -s /usr/local/apache-cassandra-1.1.7/ /usr/local/cassandra

頻繁に見るディレクトリは, bin : 実行ファイル, conf : 環境設定, lib : 関連ライブラリ です。

環境変数をいじっておきます。


$ vim ~/.bash_profile
...
export JAVA_HOME="/usr/lib/jvm/jre-1.7.0-openjdk.x86_64"
export CASSANDRA_HOME="/usr/local/cassandra" 
export CASSANDRA_CONF="$CASSANDRA_HOME/conf"

変更を適用します。


$ source ~/.bash_profile

試しに起動させてみます。


$ $CASSANDRA_HOME/bin/cassandra

ERRORがでました。


xss =  -ea -javaagent:/opt/cassandra/apache-cassandra/lib/jamm-0.2.5.jar -XX:+UseThreadPriorities -XX:ThreadPriorityPolicy=42 -Xms297M -Xmx297M -Xmn74M -XX:+HeapDumpOnOutOfMemoryError -Xss180k

ヒープ領域が足りないというエラーぽいので, cassandra-env.sh の MAX_HEAP_SIZE を 256M にしました。


$ vim $CASSANDRA_HOME/conf/cassandra-env.sh

最初はコメントアウトされています。


please set or unset MAX_HEAP_SIZE and HEAP_NEWSIZE in pairs (see cassandra-env.sh)

HEAP_NEWSIZEと MAX_HEAP_SIZEは両方必要です。 HEAP_NEWSIZEがデフォルトで800Mになっています。


The stack size specified is too small, Specify at least 228k

JVM_OPTS=”$JVM_OPTS -Xss228k” に変更しました。

Logの場所を作っておくのも忘れずに。

cassandra-nodeをインストール

nodejsからCassandraを使うためにcassandra-nodeをインストールします。


$ npm -v
1.1.65
$ npm install cassandra-client
cassandra-client@0.14.8 node_modules/cassandra-client
├── node-uuid@1.4.1
└── thrift@0.9.0

次回は, cassandraにクライアントからアクセスするところまでを書きます。