MariaDB ColumnStoreを使ってみた


あまり知られていませんが、MariaDBにはカラム型のデータベースエンジンである「[MariaDB ColumnStore](https://mariadb.com/kb/ja/mariadb-columnstore/)」があります（もしかしたら私が知らなかっただけ）
面白そうだったのでちょっと試してみました。

# Linux環境を用意する

MariaDB ColumnStoreが動作するのは、今のところ以下のいずれかとされています。

- RHEL/CentOS v6, v7
- Ubuntu 16.04 LTS
- Debian v8
- SUSE 12

今回はMacにVagrant＋VirtualBoxを使ってCentOS 7.2を立てました。
手順は[ここらへん](https://techacademy.jp/magazine/6304)を参考にしています。
Windowsなら[このあたり](http://qiita.com/kenichi_nakamura/items/d714ad3051d8e1cc6f90)を真似れば大丈夫だと思います。

[Vagrantbox.es](http://www.vagrantbox.es/)というサイトからVagrant用のイメージは入手できます。SELinuxやファイアウォールがOFFになっているものを選ぶと後の手順が楽です。

# インストール準備

[サイトにある手順](https://mariadb.com/kb/en/mariadb/preparing-for-columnstore-installation/)に沿って進めていくのですが、今回は分散並列構成を組むわけでもなく、ましてやSANストレージなどあるわけもなく、スタンドアロンでちょこっと動かすだけですので該当箇所はほとんどありません。
やらなきゃいけないのは以下くらいです。

### Boostライブラリのインストール

```bash:
yum -y install boost
```

### Developer Toolsのインストール

```bash:
yum groupinstall "Developer Tools"
yum install cmake
```

### その他のパッケージのインストール

```bash:
yum -y install expect perl perl-DBI openssl zlib file sudo libaio rsync snappy net-tools perl-DBD-MySQL
```

# MariaDB ColumnStoreのインストールと設定

### RPMパッケージのインストール

RPMパッケージが用意されているので、それをインストールします。
[こちら](https://mariadb.com/downloads/columnstore)からダウンロードすることができます。
ROOTユーザとしてインストールするか、そうでないかによって手順がちょっと変わりますが、今回はROOTユーザとしてインストールを進めます。ROOTユーザになってから以下のように。


```bash:
wget https://downloads.mariadb.com/ColumnStore/1.0.10/centos/x86_64/7/mariadb-columnstore-1.0.10-1-centos7.x86_64.rpm.tar.gz
tar xvzf mariadb-columnstore-1.0.10-1-centos7.x86_64.rpm.tar.gz
rpm -ivh mariadb-columnstore-1.0.10-1-*.rpm

```

### 設定ウィザード

RPMをインストールしたら、設定ウィザードを実行します。

```bash:
/usr/local/mariadb/columnstore/bin/postConfigure
```

すると以下のように設定を都度聞いてくるので、ポチポチ入力していってください。

```bash:
There are 2 options when configuring the System Server Type: single and multi

  'single'  - Single-Server install is used when there will only be 1 server configured
              on the system. It can also be used for production systems, if the plan is
              to stay single-server.

  'multi'   - Multi-Server install is used when you want to configure multiple servers now or
              in the future. With Multi-Server install, you can still configure just 1 server
              now and add on addition servers/modules in the future.

Select the type of System Server install [1=single, 2=multi] (2) >  1

Performing a Single Server Install.
Enter System Name (columnstore-1) > mymcs1
```

今回はテストなのでtype of System Server installで1(single)を入力していますが、実際に運用する場合は2(multi)にする必要があります。singleを選ぶと後でモジュールを増やせなくなってしまうようです。

設定の詳細については[こちらの手順](https://mariadb.com/kb/en/mariadb/installing-and-configuring-mariadb-columnstore/)をご覧ください。

### エイリアスの設定

設定ウィザードを終えたら、エイリアスを作成するコマンドを実行します。


```bash:
. /usr/local/mariadb/columnstore/bin/columnstoreAlias
```

これでColumunStore用のSQLコンソールである```mcsmysql```と、管理コンソールの```mcsadmin```が使えるようになります。

mcsmysqlは普通のmysqlのコンソールの使い方とほとんど同じです。
mcsadminの使い方は[ここ](https://mariadb.com/kb/en/mariadb/mariadb-columnstore-system-usage/)を見てください。

### 文字コードの設定

UTF-8を使いたいので、```my.cnf```と```Columnstore.xml```に以下の記述を追加します。

```/usr/local/mariadb/columnstore/mysql/my.cnf
[client]
default-character-set=utf8
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
init-connect=’SET NAMES utf8’
```

```/usr/local/mariadb/columnstore/etc/Columnstore.xml
<SystemConfig>
   <SystemLang>en_US.utf8</SystemLang>
```

設定を変更したらColumnStoreを再起動しておきます。

```bash:
mcsadmin restartSystem
```

# テスト用のデータ作成

どれほど速度が出るものなのか、データを投入して試してみたいと思います。
まずはデータベースとテーブル作成。以下のような感じで。

```text:
[root@localhost ~]# mcsmysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 15
Server version: 10.1.25-MariaDB Columnstore 1.0.10-1

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> create database hoge;
Query OK, 1 row affected (0.01 sec)

MariaDB [(none)]> use hoge;
Database changed
MariaDB [hoge]> create table mcstest (id int, dt date, category varchar(10), value int) engine=columnstore default character set=utf8;
Query OK, 0 rows affected (0.92 sec)
```

キモはcreate tableする際に```engine=columnstore```を指定している点です。
これを入れておかないとデフォルトのエンジン（バージョン10.1だとXtraDB）が選択されてしまいます。

このテーブルに投入するテキストデータは以下のような形で。レコード数は1億件用意しました。

```text:testdata.txt
1|2006-01-19|RR|3714|
2|2004-08-07|YT|4074|
3|2011-07-27|AG|4865|
4|2014-09-07|IR|1386|
5|2004-01-06|ZT|2588|
```

インポート用のユーティリティを使って上記データを取り込みます。

```bash:
/usr/local/mariadb/columnstore/bin/cpimport hoge mcstest testdata.txt
```

# SQLの計測

ではSQLを実行して速度を測ってみましょう。
同じVagrant上にインストールしたPostgreSQLにも先ほどの1億件データを突っ込んで比較してみます。
（単位はすべて秒です）

```SQL:
SELECT COUNT(*) FROM mcstest;

-> MCS: 3.385
-> PG: 11.907
```

```SQL:
SELECT SUM(value) FROM mcstest;

-> MCS: 4.528
-> PG: 14.772
```

```SQL:
SELECT category, SUM(value) FROM mcstest GROUP BY category ORDER BY category;

-> MCS: 17.357
-> PG: 28.185
```

```SQL:
SELECT category, SUM(value) FROM mcstest WHERE category IN ('AA','BB','CC','DD','EE') GROUP BY category ORDER BY category;

-> MCS: 6.573
-> PG: 25.008
```

```SQL:
SELECT category, SUM(value) FROM mcstest WHERE dt BETWEEN '2017-01-01' and '2017-07-31' GROUP BY category ORDER BY category;

-> MCS: 6.125
-> PG: 14.216
```

```SQL:
SELECT category, SUM(value) FROM mcstest WHERE category IN ('AA','BB','CC','DD','EE') and dt BETWEEN '2017-01-01' and '2017-07-31' GROUP BY category ORDER BY category;

-> MCS: 5.189
-> PG: 13.862
```

```SQL:
SELECT AVG(value) FROM mcstest WHERE value>5000;

-> MCS: 3.339
-> PG: 17.075
```

```SQL:
SELECT 
   T0.C0,
   T0.C1,
   T1.C1
FROM (
   SELECT DISTINCT
      mcstest.category AS C0,
      SUM(mcstest.value) AS C1
   FROM mcstest
   WHERE (
      mcstest.dt BETWEEN '2016-01-01' AND '2016-12-31'
   )
   GROUP BY 
      mcstest.category
) T0
LEFT OUTER JOIN (
   SELECT DISTINCT
      mcstest.category AS C0,
      SUM(mcstest.value) AS C1
   FROM mcstest
   WHERE (
      mcstest.dt BETWEEN '2015-01-01' AND '2015-12-31'
   )
   GROUP BY 
      mcstest.category
) T1
ON T0.C0 = T1.C0

-> MCS: 11.455
-> PG: 30.701
```

どちらもまったくチューニングしていない素の状態ですと **ざっくり3倍くらい** のパフォーマンスが出ていました。
分散・並列処理させられる分、まだまだ伸びしろはあるんじゃないでしょうか。
もっと詳細な計測は別の機会に試してみたいと思います。

# おまけ：Yellowfinからの接続

せっかくなのでYellowfinからの接続も確認してみます。

Yellowfinの初期状態ではMariaDBのJDBCドライバが同梱されていませんが、追加すれば使用可能です。
MariaDBのJDBCドライバは[ここ](https://downloads.mariadb.org/connector-java/)にあります。
mariadb-java-client-x.x.x.jarをダウンロードしてください。

ドライバをYellowfinに追加すれば、後は普通に使えます。

![datasource.png](https://qiita-image-store.s3.amazonaws.com/0/116818/98560ff5-3138-6cbb-c07f-a8a5361c2d85.png "datasource.png")