Cassandraアップグレード方法（v2→v3）

弊社で使用しているCassandraのアップグレードを実施した記録です。
おおまかには以下の流れです。
　1. ノードをダウンにする
　2. 新しいバージョンにあった設定ファイルに更新する
　3. アップグレードする
　4. 起動する
　5. SSTableをアップグレードする

## 参考記事
 - https://myopsblog.wordpress.com/2017/12/04/upgrade-cassandra-cluster-from-2-x-to-3-x/
 - http://cassandra.apache.org/doc/latest/

最新の公式ドキュメントはかなりTODOが多く、あまり役に立たなかった。


## 環境
## アップグレード前
- Oracle JDK8（1.8.0_141）
- Cassandra 2.1.11

## アップグレード後
 - openJDK8
 - Cassandra 3.11.4

# （１）事前準備
## 新バージョン設定ファイルの用意
http://cassandra.apache.org/download/
新しいバージョンのcassandraの設定ファイルを入手してdiffを取り、更新箇所を確認する。

※追加で記載されている箇所はほとんどデフォルトの内容で問題ないので、詳しくは言及しません。

## ノードへ設定ファイルの配置
各ノードへ新バージョン用設定ファイルを配置する。
そのときに、各ノードの合わせて設定ファイルを編集する。
具体的にはcassandra.yamlの以下情報をノードに合わせて書き換えておく。

 - initial_token
 - listen_address
 - broadcast_rpc_address
 - seeds

## ディレクトリの用意
バージョン３から追加された必要なディレクトリを追加しておく。
※デフォルトのディレクトリから設定を変えている場合のみ必要

 - cdc_raw
 - hints

```
$ sudo mkdir /path/to/cdc_raw /path/to/hints # ディレクトリの場所は設定ファイルの内容に合わせる。
```

## 新バージョンCassandra取得先の設定
http://cassandra.apache.org/download/
上記内容に沿って、各ノードでレポジトリーを設定しておく。

/etc/yum.repos.d/cassandra.repo に以下の内容を記載する。

```/etc/yum.repos.d/cassandra.repo
[cassandra]
name=Apache Cassandra
baseurl=https://www.apache.org/dist/cassandra/redhat/311x/
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://www.apache.org/dist/cassandra/KEYS
```

# （２）アップグレード作業開始直前の準備

## スナップショットの取得

もしものために各ノードでスナップショットを取っておく。

```
$ nodetool snapshot -t 2.1
```

## 定期ジョブの停止
もし、repairやバックアップのジョブを走らせていた場合は止めておく。

## 監視の実行
```
$ watch -n 5 nodetool ring
```
等で異常がないか確認しておく。

# （３）アップグレード
以下の内容を全ノードに対して行う。

## ノードの停止

全てのノードが"UP"であることを確認する。

```
$ nodetool status
```

ノードを停止する。

```
$ nodetool drain
# 他ノードからDownになっているか確認
$ sudo service cassandra stop
```

もし、そのノード上でring等を実行していると、drainしてもノードがダウンにならないので気をつけましょう。

## Java入れ替え

openJDKに入れ替える。

```
$ sudo yum install -y java-1.8.0-openjdk
$ sudo alternatives --config java
# 1.8.0-openjdkを選択
$ java -version
```
openjdkに変わっていればOK。

```
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
```
https://qiita.com/yuuman/items/a9e89d7d4899cbdaed44

## Cassandraアップデート

```
$ sudo yum remove -y cassandra21
$ sudo yum install -y cassandra cassandra-tools
```
https://cassandra.apache.org/download/

## 設定ファイルのアップデート


```
# 既存の設定ファイルの移動
$ sudo mv /etc/cassandra/conf /etc/cassandra/conf-2.1
# 新しい設定ファイルの配置
$ sudo mv conf-3.11 /etc/cassandra/conf
$ sudo chown -R root:root /etc/cassandra/conf
```

## 起動

```
$ sudo service cassandra start
```

起動時、ログファイル(/var/log/cassandra/system.log)を監視する。

全ノードのStatusがUP,StateがNormalとなる事を確認する。

```
$ nodetool status
```

アップグレードを行ったノードが正常にトラフィックを捌けていることを確認する。(Completedの値を確認)

```
$ watch -d nodetool tpstats
```

特に以下を確認

* ReadStage
* MutationStage
* RequestResponseStage


## ロールバック（非常事態対応）

途中予期せぬエラーの発生によりアップデートを中止する場合、以下の手順で行う。

Cassandraのプロセスを停止

```
$ sudo service cassandra stop
```

SSTableをバックアップから復元する前に、新バージョンのSSTableをバックアップ

```
$ mkdir -p /cassandra_data/3.11-files/$KEYSPACE/$TABLE
$ cp /cassandra_data/data/$KEYSPACE/$TABLE/*-jb-* /cassandra_data/3.11-files/$KEYSPACE/$TABLE
```

新バージョンのSSTablesを削除

```
$ rm /cassandra_data/data/$KEYSPACE/$TABLE/*
```

スナップショットのファイルを復元

```
$ cp /cassandra_data/data/$KEYSPACE/$TABLE/snapshots/2.1/* /cassandra_data/data/$KEYSPACE/$TABLE/
```

repairを実行

```
$ nodetool repair
```

# （４）アップグレード後処理

## SSTableをアップグレード

各ノードのSSTableをアップグレードする。
※時間がかかります。

```
$ nodetool upgradesstables
```

こちらで進行状況の確認

```
$ nodetool compactionstats
```

結果を確認

```
$ find /path/to/data/ -type f | grep -v md- | grep -v "/snapshots" # dataディレクトリは設定に合わせる
# なにも結果がでなければOK
```

## snapshotを削除

```
$ nodetool clearsnapshot -t 2.1
```

# （５）定期実行ジョブを再開

止めていた定期ジョブを再開する。

# 裏話

一部アプリケーションのcassandra関連のライブラリが古いバージョンだったため、障害が発生して、心臓にダメージを受けました。
検証は入念に行いましょう。