こんにちは。アイフラッグの社内システム担当のYMです。
今回は、私の方から、、、。
社内にたまったデータの活用方法として、データをDWHなどにためて、それをBIツールなどを使って分析するということがあるかと思います。
データ量が少ない時は、特に問題にならないのですが、データ量が多くなってくると、データ検索のレスポンスが問題となってくる場合がありがちです。
そんな時、分析に使用するデータベースを、一般的なDBMS(行指向)から、列指向DBMSに置き換えることによって、レスポンスを向上させることができます。
今回は、列指向DBMSの一つである、InfiniDB(コミュニティ版)を導入して、MySQL(InnoDB)とのレスポンスの違いを試してみたいと思います。
1.http://www.infinidb.org/ から、InfiniDB(コミュニティ版)をダウンロードします。
#ユーザ登録が必要となります。
[root@localhost src]# ls
calpont-infinidb-2.2.11-1.x86_64.rpm.tar.gz
2.展開して、インストールします。
InfiniDBは、MySQLがベースとなっているので、一緒にMySQLもインストールされます。
[root@localhost src]# tar xvzf calpont-infinidb-2.2.11-1.x86_64.rpm.tar.gz
[root@localhost src]# ls
calpont-2.2.11-1.x86_64.rpm calpont-mysql-2.2.11-1.x86_64.rpm
calpont-infinidb-2.2.11-1.x86_64.rpm.tar.gz calpont-mysqld-2.2.11-1.x86_64.rpm
[root@localhost src]# rpm -ivh calpont*.rpm
3.インストール完了後、環境に合わせて初期設定をし、InfiniDBの初期構築を行います。
[root@localhost mysql]# /usr/local/Calpont/bin/install-infinidb.sh
4.InfiniDBを起動します。
[root@localhost mysql]# service infinidb start
5.データベースの初期設定を行います。
#このあたりは、MySQLと同じです。
[root@localhost ~]# mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.1.39 MySQL Community / Calpont InfiniDB Community 2.2.11-1 Final (COSS LA)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
InfiniDBにアクセスするユーザには、データベース:infinidb_vtableへのアクセス権限が必要となります。
mysql> GRANT ALL PRIVILEGES ON `infinidb_vtable`.* TO 'test'@'localhost';
InfiniDBのストレージエンジンが入っています。
mysql> show engines;
+------------+---------+-----------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+------------+---------+-----------------------------------------------------------+--------------+------+------------+
| CSV | YES | CSV storage engine | NO | NO | NO |
| InfiniDB | YES | Calpont InfiniDB storage engine | YES | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
+------------+---------+-----------------------------------------------------------+--------------+------+------------+
5 rows in set (0.00 sec)
今回は、InnoDBも使えるようにしておきます。
mysql> INSTALL PLUGIN INNODB SONAME 'ha_innodb.so';
Query OK, 0 rows affected (0.94 sec)
mysql> show engines;
+------------+---------+------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+------------+---------+------------------------------------------------------------+--------------+------+------------+
| CSV | YES | CSV storage engine | NO | NO | NO |
| InnoDB | YES | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| InfiniDB | YES | Calpont InfiniDB storage engine | YES | NO | NO |
+------------+---------+------------------------------------------------------------+--------------+------+------------+
6 rows in set (0.00 sec)
InnoDBと、InfiniDBで同じ内容のテーブルを作成し、データを適当に入れてクエリのレスポンスを比較してみました。
・InnoDB
mysql> select count(*) from sample_innodb;
+----------+
| count(*) |
+----------+
| 1188452 |
+----------+
1 row in set (8.45 sec)
・InfiniDB
mysql> select count(*) from sample_infinidb;
+----------+
| count(*) |
+----------+
| 1188452 |
+----------+
1 row in set (0.09 sec)
レコード数をCOUNTしただけですが、すでにInfiniDBのレスポンスがよいことが分かります。
次に、2つのテーブルでJOINしたものを集計する同じクエリをそれぞれに投げてみます。
・InnoDB
mysql> select sample_dim_innodb.NM_ID ,sum(sample_innodb.DATA) from sample_innodb left join sample_dim_innodb on sample_innodb.NM_ID = sample_dim_innodb.NM_ID group by sample_dim_innodb.NM_ID order by sample_dim_innodb.NM_ID;
+-------+-------------------------+
| NM_ID | sum(sample_innodb.DATA) |
+-------+-------------------------+
| 1 | 211849828 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 52 | 122460 |
+-------+-------------------------+
48 rows in set (40.88 sec)
・InfiniDB
mysql> select sample_dim_infinidb.NM_ID ,sum(sample_infinidb.DATA) from sample_infinidb left join sample_dim_infinidb on sample_infinidb.NM_ID = sample_dim_infinidb.NM_ID group by sample_dim_infinidb.NM_ID order by sample_dim_infinidb.NM_ID;
+-------+---------------------------+
| NM_ID | sum(sample_infinidb.DATA) |
+-------+---------------------------+
| 1 | 211849828 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 52 | 122460 |
+-------+---------------------------+
48 rows in set (0.36 sec)
InnoDBで40秒かかったクエリが、InfiniDBでは、0.3秒で返ってきました。
結果として、InfiniDBの方が、InnoDBよりも検索のレスポンスが良いことが分かります。
#単純なクエリでこれだけの差が出るので、OLAPなど、大量データに対して複雑なクエリを投げる場合は、もっとメリットが受けられると思います。
InfiniDBが検索処理に対してのレスポンスがよいことが分かりましたが、
運用するにはいくつか注意点がありますので、少しまとめておこうと思います。
・SELECTをしながらINSERTが出来ない。
#コミュニティ版の制限になります。
ERROR 138 (HY000): IDB-1009: Insert with Select is only available in InfiniDB Enterprise.
・同時に複数のトランザクションを実行できない。
#同様に、同時に2つのクエリーも発行できないようです。
・InfiniDBとInfiniDB以外のテーブルでJOINが出来ない。
ERROR 1105 (HY000): IDB-7001: Non InfiniDB table(s) on the FROM clause.
#以下の設定をすれば回避できるようですが、InfiniDBを使用するメリット(レスポンス)が受けられなくなってしまいます。
infinidb_vtable_mode = 0
・インデックスや制約の使用ができないようです。
ERROR 138 (HY000): IDB-4014: Constrants are currently not supported in InfiniDB.
・Auto Incrementが使用できないようです。
#コミュニティ版の制限になります。
・VARCHAR型の長さについて、MyISAMやInnoDBとは異なりバイト長で定義するようです。
#他にもデータタイプについてはいくつか相違があるようです。
・INSERTなど、更新系の処理はInnoDBよりもはるかに遅い。
#データ更新が発生するデータベースには向かないです。
以上のように、InfiniDBはいくつか制限があるものの、主にに参照用途で使用される、
BIシステムなどを使った大量データ分析でのレスポンス向上には、高い効果を発揮するのではないでしょうか。