VoltDBの開発者向けドキュメントのまとめ（9章：クラスタでVoltDBを使用する）

# はじめに

VoltDBの開発者向けの公式ドキュメント[Using VoltDB](https://docs.voltdb.com/UsingVoltDB/index.php)のまとめです。対象のバージョンはv8.3です。

今回は9章です。

他にも以下をまとめています。
・[3. データベースの起動](https://qiita.com/mkyz08/items/647459cfe67641e4b888)
・[7. アプリケーション開発の簡略化](https://qiita.com/mkyz08/items/ff9d15cf050af6508964)
・[9. クラスタでVoltDBを使用する](https://qiita.com/mkyz08/items/80f29883a006d1f393e2)
・[13. VoltDBデータベースの保存と復元](https://qiita.com/mkyz08/items/552e83b231e02d47314c)

なお、本投稿のまとめ元である「Using VoltDB」のライセンスはAGPLであり、これらのまとめ投稿はAGPLが適用されます。

# 9. クラスタでVoltDBを使用する

・VoltDBは1台のサーバ上で複数のパーティションを作成できるため、1台でVoltDBを実行しても並列性の利点がある。しかし、1台のサーバーでのメモリ量と処理能力には実質的に制限がある。
・ほぼリニアなスケーラビリティを達成するために、サーバをクラスタに追加するだけでメモリ容量と処理能力（つまりパーティションの総数）を増やすことができる。
・クラスタを利用することデータベースの可用性が向上し、サーバの障害やネットワークの障害から保護することができる。

本章ではVoltDBサーバーのクラスタを作成する方法について説明する。また、追加のメモリ容量や処理能力が必要な場合にクラスタを拡張する（ノードを追加する）方法についても説明する。

## 9.1. データベースクラスタの起動

・VoltDBクラスタの起動は、単一のサーバ上でVoltDBを起動するのと同様。
・データベースの構成を変更するには、voltdb initを使用してルートディレクトリを初期化するときに構成ファイルを指定する。

・クラスタを起動するには voltdb startコマンドを使用する。
--count引数を使用して、クラスター内のノード数を指定する。
--host引数を使用して、クラスタ内の1つ以上の（ホスト）ノードを指定する。
  クラスタのすべてのノードで同じコマンドを実行する。 
・例えば、5台のサーバのクラスタを作成し、ノードserver2とserver3をホストとして選択する場合は、5台のすべてのノードで次のコマンドを実行する。

```
  $ voltdb start --host=server2,server3 --count=5 
```

・停止したクラスタを再度起動する場合も同様。
・以下のように--host引数でクラスタ内のすべてのノードを指定し、サーバ数を省略することもできる。

```
  $ voltdb start --host=server1,server2,server3,server4,server5
```

・データベースクラスタが実行されると、リーダーの特別な役割が完了し、すべてのノードがピア（平等）になる。 


## 9.2. クラスタ構成の変更

・クラスタの構成を変更する場合、クラスタを停止し、voltdb initコマンドを構成ファイルを指定して各ノードを初期化する。
・クラスタの全てのノードで同じ構成ファイルを指定する必要がある。
・例えば

```
  $ voltdb init --config=deployment.xml 
```

・データベースの多くの機能では、設定を変更する場合、次のいずれかの方法でデータベースの実行中に変更できる。
    WebベースのVoltDB Management Centerを使用して、[管理]タブで変更する

[補足]Webベースでは、鉛筆マークがついているところが実行中に変更可能。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/179607/1ccc4662-6e6b-9512-2671-2af63ddb575f.png)


    元の構成ファイルを編集して、 voltadmin updateコマンドで変更を適用する

・たとえば、セキュリティ設定の変更、構成のインポートとエクスポート、およびリソース制限を実行中に変更できる。いずれの方法でも変更はVoltDBに保存される。
・ただし、データベースの実行中はK-Safety値またはサーバーごとのパーティション数等は変更できない。クラスタの静的構成オプションを変更するには、データベースの内容を保存し、初期化してから、データベースを再起動して復元する必要がある。手順は次のとおり。

1.データベースを一時停止する（ voltadmin pause）
2.データベースの内容のスナップショットを保存する（ voltadmin save {path} {file-prefix} ）
3.データベースをシャットダウンする（ voltadmin shutdown ）
4.新しい構成ファイルと--force引数でルートディレクトリを初期化する（ voltdb init --force --config=file ）
5.管理モードでデータベースを再起動する（ voltdb start --pause ）
6.スナップショットを復元する（ voltadmin restore {path} {file-prefix} ）
7.通常の操作を再開する （ voltadmin resume ） 

・保存と復元の使用方法については 、第13章VoltDBデータベースの保存と復元を参照してください。
・ベンチマークを実行するときに、パーティション数の変更、サーバーの数の削減、またはその他の静的構成オプションの調整が必要な場合は、この方法が推奨される。
・ただし、単純にクラスタにノードを追加してメモリ容量を追加や処理能力を向上させたりする場合は、データベースの実行中に実施できる。実行中にノードを追加することは、次のセクションで説明するようにElasticスケーリングと呼ばれる。


### 9.2.1. Elasticスケーリングを使用したノードの追加

・クラスタが実行中に新しいノードを追加する場合、voltdb initコマンドを使用して初期化し、voltdb startコマンドに--add引数をつけて開始する。
・例えば、ServerAがすでにメンバーになっているクラスタにノードServerXを追加する場合、ServerXで次のコマンドを実行する。

```
 $ voltdb init --config=deployment.xml
 $ voltdb start --add --host=ServerA 
```

Elasticスケーリングでノードが追加されると、クラスタは次のタスクを実行する。
1.クラスタは新しいサーバーの存在を確認する。
2.現在のスキーマと構成設定のコピーが新しいノードに送信される。
3.十分なノードが追加されると、レプリケートテーブルのコピーと必要なパーティションテーブルが新しいノードに送信される。
4.データが再配布（またはリバランス）すると、追加されたノードはクラスタのメンバーとして参加する。 

Elasticスケーリングを使用してクラスタを拡張するときの注意事項。

・K-safeクラスタの構成を維持するためには、十分な数のノードを追加する必要がある。つまり、K+1個のノード。例えば、クラスタのK-safety値が2の場合、クラスタを展開するために一度に3つのノードを追加する必要がある。クラスタがK-safe（つまりK-safety値が0）でない場合は一度に1つのノードを追加できる。
・K-safeクラスタにノードを追加すると、最初に追加されたノードは上記のステップ1と2を完了するが、正しいノード数が追加されるまでステップ3と4を完了しない。
・クラスタがリバランスされている間（ステップ3）、データベースは引き続きクライアントからのリクエストを処理する。ただし、データベースの負荷とリバランスのデータ量に応じて、リバランスにはかなりの時間がかかる。
・Elasticスケーリングが完了するとデータベース構成の変更が保存される。次回クラスタを起動する際は、voltdb startコマンドの--count引数にノード追加後のサーバー数を指定する。 


### 9.2.2. 新しいノード追加時のリバランスの設定

・（K-safety値に基づいて）必要な数のノードを追加すると、VoltDBはクラスタをリバランスし、既存のパーティションから新しいノードにデータを移動する。
・リバランス中、データベースは使用可能であり、クライアントからのトランザクション処理を受け付ける。
・リバランスの所要時間は、リバランスタスクの処理頻度と各トランザクションの移動量の2つの要素に依存する。

・リバランスタスクは全てトランザクションなので、データベースのACID準拠のトランザクションモデル内で動作する。
・2つ以上のパーティション間でデータを移動するため、マルチパーティション・トランザクションになる。これは、各リバランス処理は保留中のクライアントトランザクションの待ち時間に段階的に追加できることを意味する。
・リバランス完了までの時間と、リバランス中のクライアントトランザクションへの影響を構成ファイルの\<elastic>要素の2つの属性で制御できる。

- duration（期間）属性は、各リバランストランザクションにかかる時間の目標値をミリ秒単位で設定する。 デフォルトは50ミリ秒です。
- throughput（スループット）属性は、リバランストランザクションによって処理されるMB/秒の目標値を設定する。 デフォルトは2MBです。 

・VoltDBは各トランザクションで移動するデータ量を調整して、durationの値に近づける。durationを長くするとトランザクションごとに移動するデータ量が増加する。durationを短くするとトランザクションあたりのデータ量が減少する。
・スループットを変更すると、1秒あたりに移動するデータ量を変更する。スループットを増やすと、1秒あたりのトランザクション数が増加する。スループットを減らすとトランザクション数が減少する。

・たとえば、次の構成ファイルでは、データベースを開始する前に　durationを15ミリ秒に設定し、　throughputを1MB/秒に設定している。

```
<deployment>
   . . .
   <systemsettings>
       <elastic duration="15" throughput="1"/>
   </systemsettings>
</deployment>
```