はじめに
VoltDBは2018年10月時点で最新バージョンがv8.3.1です。
最新版のv8.3.1をシングル構成で構築します。
v9.0もリリースされていますが、インストール手順はv8.3.xと同じです。
クラスタ構成での構築手順は以下の記事になります。
インメモリデータベース VoltDBの最新バージョン(v8.3.1)をインストールする(クラスタ構成)
VoltDBとは
VoltDBはインメモリRDBで、PostgreSQLに携わったマイケル・ストーンブレーカーにより設定されています。
NoSQLより高速でありながら、SQLを利用できトランザクションもサポートされています。
最近はあまり話題にならない(?)ですが、「2011年の国民的アイドルグループ選抜総選挙」で利用されたときに話題になりました。
私も購入したのですが、舞台裏は以下の本に書いています(技術的に深い内容ではありませんが)。
過負荷に耐えるWebの作り方 ~国民的アイドルグループ選抜総選挙の舞台裏 (Software Design plus)
興味がある方は以下も参考になるかと思います。
VoltDBを使ってみる
https://qiita.com/ytake/items/4da625997079716404ad
VoltDB(Wikipedia)
https://ja.wikipedia.org/wiki/VoltDB
環境と構築手順の概要
VirtualBox上にCentOS 7.4を1台起動し、VoltDBをシングル構成で構築します。
ローカル環境なので、firewalldとSELinuxは無効化しています。
サーバは以下の1台です。
・192.168.10.171 volt1
構築では以下の順番で実施します。
- OpenJDKのインストール
- NTPの設定
- VoltDBのインストール
- VoltDB起動
- テーブルを作成
構築手順
OpenJDKのインストール
OpenJDK 8かOracleJDK 8をインストールします。
今回はOpenJDKをインストールしましたが、OracleJDKが推奨されています。
[2018/10/4追記]
OracleJDKが推奨されていますが、OpenJDKもサポートされています。
# yum install java-1.8.0-openjdk-devel
# java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
JAVA_HOMEを設定し、PATHにJavaのパスを追加しています。
# echo "export JAVA_HOME=$(readlink -e $(which java)|sed 's:/bin/java::')" > /etc/profile.d/java.sh
# echo "PATH=\$PATH:\$JAVA_HOME/bin" >> /etc/profile.d/java.sh
# source /etc/profile
NTPの設定
クラスタ構成の場合はVoltDBの各サーバ間での時刻のずれが100ms未満である必要があるため、NTPで同期させます。今回はシングル構成なので省略します。
firewalldの設定
VoltDBがデフォルトで使用するポートの一覧は以下のとおりです。
Client Port: 21212
Admin Port: 21211
Web Interface Port (httpd): 8080
Web Interface Port (with TSL/SSL enabled): 8443
Internal Server Port: 3021
Replication Port: 5555
Zookeeper port: 7181
この内、「Web Interface Port (with TSL/SSL enabled)」と「Replication Port」は使用する場合だけポートを解放すればよいです。
※3021, 5555, 7181はシングル構成では不要かもしれません。
firewall-cmd --add-port=21212/tcp --permanent
firewall-cmd --add-port=21211/tcp --permanent
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --add-port=3021/tcp --permanent
firewall-cmd --add-port=5555/tcp --permanent
firewall-cmd --add-port=7181/tcp --permanent
firewall-cmd --add-port=123/udp --permanent
firewall-cmd --add-port=22/tcp --permanent
firewall-cmd --reload
以下のコマンドで設定を確認します。
firewall-cmd --list-ports --zone=public
21212/tcp 21211/tcp 8080/tcp 3021/tcp 5555/tcp 7181/tcp 22/tcp
VoltDBのインストール
VoltDBのモジュールは以下の公式サイトから「COMMUNITY EDITION」をダウンロードします。
一部使用できない機能もありますが、プロダクション環境でも十分な機能が網羅されている(と思います)。
まず、voltdb-community-8.3.1.tar.gzを/opt以下に展開し、シンボリックリンクを作成します。
# tar xvzf voltdb-community-8.3.1.tar.gz -C /opt/
# ln -s /opt/voltdb-community-8.3.1/ /opt/voltdb
VoltDBでは透過的なHugePages(Transparent HugePage)を無効化する必要があります。これを実行しないとVoltDBが起動しません。
これだとOS起動後に毎回実行しないといけない。
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# echo never > /sys/kernel/mm/transparent_hugepage/defrag
OS起動時に自動実行するにはrc.localを編集します。
/etc/rc.localに以下を追記します。(CentOS 7.4の場合)
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
また、rc.localに実行権限も付与してください。
# chmod u+x /etc/rc.d/rc.local
最後にOSを再起動し、以下のコマンドを実行して両方ともneverになっていることを確認します。
# cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
# cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never]
今回使用するサーバ1台をhostsに入れます。
vi /etc/hosts
「/etc/hosts」に追加する内容は以下のとおりです。
192.168.10.171 volt1
次に「/opt/voltdb/bin」をパスに追加します。
vi /etc/profile.d/voltdb.sh
追加する内容は以下のとおりです。
export PATH="$PATH:/opt/voltdb/bin"
すぐに反映させるため、以下のコマンドを入力します。
source /etc/profile
スキーマ・プロシージャの作成
テーブルやプロシージャは、インストール後に作成することもできるので、必ずしもインストール前に準備する必要はありません。
voltdbユーザの作成
VoltDBの操作はvoltdbユーザを使用しますので、まずはユーザを作成します。
# useradd -s /bin/bash -m voltdb -p voltdb
# chown -R voltdb:voltdb /opt/voltdb-community-8.3.1/
以降の操作はvoltdbユーザを使用して実行します。
VoltDBの初期化と起動
標準設定でVoltDBを初期化します。
※-fをつけると強制的に初期化します。今回は初回なので必要ないですが既に初期化済みの場合は-fをつけます。
# cd /opt/voltdb
# voltdb init -D /opt/voltdb -f
VoltDBを起動します。
# cd /opt/voltdb
# voltdb start -D /opt/voltdb -B
起動時のオプションは以下のとおりです。今回はシングル構成なので、-Hと-cは省略できます。
-D: VoltDBのルートディレクトリ(init時と同じディレクトリを指定)
-H: 接続先のクラスタのサーバ
-c: クラスタ中のサーバ台数
-B: バックグラウンドで実行
VoltDBのWeb画面を開く
VoltDBでは標準でSQLを実行したり、パフォーマンスを見ることができるWebアプリケーションが起動します。
各サーバで実行されており、8080ポートでアクセスできます。
画面は以下のようになります。
テーブルを作成する
VoltDBのコンソール(sqlcmd)から、テスト用のテーブルを作成します。
$ sqlcmd
1> CREATE TABLE TEST_A (
2> ID varchar(50) NOT NULL,
3> DATA smallint,
4> PRIMARY KEY (ID)
5> );
Command succeeded.
6> PARTITION TABLE TEST_A ON COLUMN ID;
Command succeeded.
クライアントプログラムを実行する
先ほど作成したテーブルへアクセスするクライアントプログラムを作成します。
package sample;
import java.io.IOException;
import org.voltdb.VoltTable;
import org.voltdb.VoltType;
import org.voltdb.client.Client;
import org.voltdb.client.ClientFactory;
import org.voltdb.client.ClientResponse;
import org.voltdb.client.NoConnectionsException;
import org.voltdb.client.ProcCallException;
public class SingleTest {
public static void main(String[] args) throws NoConnectionsException, IOException, ProcCallException {
Client client = ClientFactory.createClient();
client.createConnection("volt1");
String msgId = "test1";
VoltTable[] results;
ClientResponse res;
res = client.callProcedure("TEST_A.insert", msgId, 1);
if (res.getStatus() == ClientResponse.SUCCESS) {
System.out.println("Insertに成功");
}
res = client.callProcedure("TEST_A.select", msgId);
results = res.getResults();
while (results[0].advanceRow()) {
Short value = (Short) results[0].get(1, VoltType.SMALLINT);
System.out.println("value = " + value);
}
}
}
以下でVoltDBのサーバへ接続しています。
Client client = ClientFactory.createClient();
client.createConnection("volt1");
VoltDBでDMLを実行する場合はストアドプロシージャを呼び出します。
テーブルを作成すると、insert, select, update, deleteのデフォルトストアドプロシージャが自動生成されます。
以下は、insertとselectのデフォルトストアドプロシージャの実行例です。
res = client.callProcedure("TEST_A.insert", msgId, 1);
res = client.callProcedure("TEST_A.select", msgId);
自動で生成されたデフォルトストアドプロシージャは以下で確認できます。
$ sqlcmd
> list procedures;
~省略~
--- User Procedures ------------------------------------------
TEST_A.delete varchar
TEST_A.insert varchar, smallint
TEST_A.select varchar
TEST_A.update varchar, smallint, varchar
TEST_A.upsert varchar, smallint