Cassandra2系のクラスターをRHEL系LInuxに構築する

# Cassandra2系のクラスターをRHEL系LInuxに構築する

Cassandra2系でのクラスタのベンチマークを取りたかったのでRHEL系LInuxにインストールしました。
*ここから先の作業は`sudo su -`でrootになってからおこなっています。*

## 1. jnaのインストール
[インストールガイド](http://www.datastax.com/documentation/cassandra/2.0/cassandra/install/installRHEL_t.html)を見ると、Oracle Java7の最新版jreとJNA(>=3.2.7)をインストールしろと書いてあるので、これらをインストールします。

インストールパッケージはyumで管理したいので、yumでさくっと入れてしまいたいところなのですが・・・

私の環境(CentOS6.4)で`yum install jna`を行おうとするとjnaの3.2.4が入ってしまいますΣ(￣□￣; )
なので、yumのリポジトリにfedora16のリポジトリを追加してこちらのrpmパッケージを使います。

```zsh:/etc/yum.repos.d/fedora16.repo
[fedora16]
name = Fedora16
baseurl =http://ftp.riken.jp/Linux/fedora/releases/16/Everything/$basearch/os/
enabled = 1
gpgcheck = 1
```

```zsh:zsh
% rpm --import http://ftp.riken.jp/Linux/fedora/releases/16/Everything/x86_64/os/RPM-GPG-KEY-fedora
```

jnaをインストールします。こうするとopenjdk-1.7.0もインストールされます。

```zsh:zsh
% yum -y install jna
```

## 2. javaのインストール

Cassandraはopenjdkでも動くのですがOracle Javaを使えと書いてあるので、Oracle Javaもインストールします。
jdk-7u51-linux-x64.rpmは[Oracleのダウンロードサイト](http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html)からダウンロードしておきます。

```zsh:zsh
% yum -y install jdk-7u51-linux-x64.rpm

# /usr/javaにインストールされるので、
% ll /usr/java
合計 4
lrwxrwxrwx 1 root root   16  3月  7 11:25 2014 default -> /usr/java/latest
drwxr-xr-x 8 root root 4096  3月  7 11:25 2014 jdk1.7.0_51
lrwxrwxrwx 1 root root   21  3月  7 11:25 2014 latest -> /usr/java/jdk1.7.0_51

# rootの.XXrcにJAVA_HOMEを設定しておきます。
% echo "export JAVA_HOME=/usr/java/latest" >> /root/.zshrc
```

しかし、このままではjnaのインストール時に一緒に入ってしまったopenjdkがデフォルトのjavaになっています。

```zsh:zsh
% java -version
java version "1.7.0_51"
OpenJDK Runtime Environment (rhel-2.4.4.1.el6_5-x86_64 u51-b02)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
```

alternativesでOracle Javaを使うように切り替えましょう。

```zsh:zsh
#                      実行するリンク グループ 実行するコマンドのパス      優先順位
% alternatives --install /usr/bin/java java /usr/java/latest/bin/java 17051

# Oracle Javaを選択します
% alternatives --config java

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

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

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2

% java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
```

*私はjavaのプロファイリングツールなども使うつもりなのでjreではなくjdkをインストールしました。*

## 3. DataStax yumリポジトリの追加
DataStaxのリポジトリを/etc/yum.repos.d/に追加します。

```zsh:/etc/yum.repos.d/datastax.repo
[datastax]
name = DataStax Repo for Apache Cassandra
baseurl = http://rpm.datastax.com/community
enabled = 1
gpgcheck = 0
```

## 4. cassandra2.0のインストール

yumでインストールします。

```zsh:zsh
% yum -y install cassandra20
```

特に問題なくはいります(*^^)v

## 5. Cassandraのディレクトリ構造

Cassandraをインストールすると下記のようにディレクトリや設定ファイルが作成されます。

* `/etc/cassandra/`  ・・・設定ファイル
  * `/etc/cassandra/conf/cassandra-env.sh`  ・・・JVMヒープ等の設定
  * `/etc/cassandra/conf/cassandra.yaml`  ・・・メインの設定ファイル
  * `/etc/cassandra/conf/log4j-server.properties`  ・・・ログ関連の設定
* `/var/lib/cassandra` ・・・データ、キャッシュ、コミットログディレクトリ

## 6. 起動してみる

```zsh:zsh
% /etc/init.d/cassandra start
```

試しにcqlshでつないでみます。

```zsh:zsh
% cqlsh
Connected to Test Cluster at localhost:9160.
[cqlsh 4.1.1 | Cassandra 2.0.5 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
Use HELP for help.
cqlsh>
```

ふつうにつながります。

## 7. クラスターを構成する

Cassandraのクラスターを構成するために、いったんCassandraを停止します。
*※私は3台のマシンでクラスターを構築しました。*

```zsh:zsh
% /etc/init.d/cassandra stop
```

/etc/cassandra/conf/cassandra.yamlの
* listen_address
* rpc_address
* seeds
* auto_bootstrap(最初のノード以外)
を編集します。

### まずは1つめのサーバのcassandra.yamlを編集します。

```zsh:/etc/cassandra/conf/cassandra.yaml
# listen_addressをlocalhostから、他のサーバと通信可能なホスト名もしくはIPアドレスに変更します。
#listen_address: localhost
listen_address: node1.example.jp
# または、listen_address: 192.168.0.101

# rpc_addressもlocalhostから、他のサーバと通信可能なホスト名もしくはIPアドレスに変更します。
#rpc_address: localhost
rpc_address: node1.example.jp
# または、rpc_address: 192.168.0.101

seed_provider:
    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
        #- seeds: "127.0.0.1"
        - seeds: "node1.example.jp"
        # または - seeds: "192.168.0.101"
```

保存したらCassandraを再起動します。
7000番ポートをlistenしていることを確認します。

```zsh:zsh
% /etc/init.d/cassandra start
% lsof -i :7000
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    27179 cassandra   47r  IPv4 103830      0t0  TCP node1:afs3-fileserver (LISTEN)
```

### 他のサーバのcassandra.yamlも編集します。

```zsh:/etc/cassandra/conf/cassandra.yaml
# 2台めもlisten_addressをlocalhostから、他のサーバと通信可能なホスト名もしくはIPアドレスに変更します。
#listen_address: localhost
listen_address: node2.example.jp
# または、listen_address: 192.168.0.102

# rpc_addressもlocalhostから、他のサーバと通信可能なホスト名もしくはIPアドレスに変更します。
#rpc_address: localhost
rpc_address: node2.example.jp
# または、rpc_address: 192.168.0.102

seed_provider:
    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
        #- seeds: "127.0.0.1"
        - seeds: "node1.example.jp"
        # ↑ここは１台めのアドレスを指定したままでだいじょうぶです。
        # または - seeds: "192.168.0.101"
```

保存したらCassandraを再起動します。3台めも同様に。
ここで1台めのマシンでlsofすると、、、

```zsh:zsh
% lsof -i :7000
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    27179 cassandra   47r  IPv4 103830      0t0  TCP node1:afs3-fileserver (LISTEN)
java    27179 cassandra  114u  IPv4 110100      0t0  TCP node1:afs3-fileserver->192.168.0.102:60440 (ESTABLISHED)
java    27179 cassandra  115u  IPv4 110072      0t0  TCP node1:afs3-fileserver->192.168.0.102:60439 (ESTABLISHED)
java    27179 cassandra  116u  IPv4 110099      0t0  TCP node1:60887->192.168.0.102:afs3-fileserver (ESTABLISHED)
java    27179 cassandra  117u  IPv4 110535      0t0  TCP node1:51776->192.168.0.103:afs3-fileserver (ESTABLISHED)
java    27179 cassandra  118u  IPv4 110536      0t0  TCP node1:afs3-fileserver->192.168.0.103:60988 (ESTABLISHED)
```

2,3台めのマシンと接続していることが確認できます。

cassandraに付属のnodetoolでステータスを確認してみます。

```zsh:zsh
% nodetool -h localhost status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address      Load       Tokens  Owns (effective)  Host ID                               Rack
UN  192.168.0.102  94.26 KB   256     62.5%             c1cbd878-4537-4ff1-97be-a77934f855bf  rack1
UN  192.168.0.103  106.04 KB  256     72.8%             34b9978b-02c1-40dd-8d79-db5f9467136e  rack1
UN  192.168.0.101  94.31 KB   256     64.7%             7ddbd35e-89c3-4b79-87ce-a96a86761734  rack1
```

## 8. keyspace, tableを作ってデータがクラスタリングされることをたしかめる

```sql
% csqlsh node1.example.jp
cqlsh> create keyspace test with replication = {'class':'SimpleStrategy', 'replication_factor':2 };
cqlsh> use test;
cqlsh:test> create table z ( id int PRIMARY KEY, value text );
cqlsh:test> insert into z ( id , value ) values ( 1, 'abc' );
cqlsh:test> insert into z ( id , value ) values ( 2, 'def' );
```

`test`keyspaceに`z`というテーブルを作成し、データをいれました。
これを他のマシンからSELECTできるかためしてみます。

```sql
% csqlsh node2.example.jp
cqlsh> use test;
cqlsh:test> select * from z;

 id | value
----+-------
  1 |   abc
  2 |   def

(2 rows)
```

こんな感じでデータが帰ってきます(*^^)v