先日インストールしたDrizzleの簡単な性能評価をしてみました.
速度はもちろんですが,どれくらいMySQLと互換性があるか調べたかったのです.
Drizzle自体は,先日インストールした通りです.
DrizzleをFreeBSDにインストールしてみた - なぜか数学者にはワイン好きが多い
MySQLは,普通にMySQLのサイトからFreeBSD用のMySQL 5.1をダウンロードして,
MySQL :: Download MySQL Community Server
BINARY-INSTALLに従ってインストールしました.
まずDrizzleを立ち上げます.
# drizzled --datadir=/tmp/drizzle.data/ -u tetu-s --console-enable --port=3306 InnoDB: The InnoDB memory heap is disabled InnoDB: Neither mutexes nor rw_locks use GCC atomic builtins. InnoDB: highest supported file format is Barracuda. InnoDB: The log sequence number in ibdata files does not match InnoDB: the log sequence number in the ib_logfiles! InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace information from the .ibd files... InnoDB: Restoring possible half-written data pages from the doublewrite InnoDB: buffer... InnoDB: Last MySQL binlog file position 0 0, file name UNUSED InnoDB Plugin 1.0.4 started; log sequence number 5179208 Listening on 0.0.0.0:3306 Listening on 0.0.0.0:4427 drizzled: Forcing close of thread 0 user: '' drizzled: ready for connections. Version: '2009.12.1251' Source distribution (drizzle)
そして別なターミナルでDrizzleクライアントを立ち上げて,テストに使うデータベース「test」を作ります.
> drizzle Welcome to the Drizzle client.. Commands end with ; or \g. Your Drizzle connection id is 3 Server version: 2009.12.1251 Source distribution (drizzle) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. drizzle> show databases; +--------------------+ | Database | +--------------------+ | information_schema | +--------------------+ 1 row in set (0 sec) drizzle> CREATE DATABASE test; Query OK, 1 row affected (0.46 sec) drizzle>
コマンドはmysqlクライアントと同じです,ここまでは.
次にMySQLを立ち上げます.
# /usr/local/mysql/bin/mysqld_safe --user=mysql mysqld_safe Logging to '/usr/local/mysql/data/localhost.err'. mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql/data
そして同様に,テスト用のデータベース「test」を作ります.
# /usr/local/mysql/bin/mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.1.41 MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | +--------------------+ 2 rows in set (0.00 sec) mysql> CREATE DATABASE test; Query OK, 1 row affected (0.04 sec)
サーバの準備が出来たので,プログラムを作ります.
以前と同様に,
C++によるMySQLの高速アクセス予備実験 - なぜか数学者にはワイン好きが多い
c++とmysql++を使います.
DrizzleはMySQLプロトコルをサポートしているので,プログラムは改造無しで一つで大丈夫と信じて,OpenMPでスレッド対応にした以下のものだけを使います.
#include <omp.h>
#include <stdlib.h>
#include <mysql++.h>
using namespace std;
using namespace mysqlpp;
static const int MAX_ROW=20000; // DBにINSERTする行数
void Abort(string e)
{
cout<<e<<endl;
exit(1);
}
int database_reset(Connection &db_conn)
{
Query query = db_conn.query();
query<<"DROP TABLE IF EXISTS bench"; // テーブルがあったら消して作り直す
if(query.execute()==false) Abort(query.error());
query<<"CREATE TABLE bench (mykey INT NOT NULL, value VARCHAR(255) NOT NULL, PRIMARY KEY (mykey)) ENGINE = INNODB;";
if(query.execute()==false) Abort(query.error());
return(0);
}
int generate_data_table(vector<string> &table)
{
for(int key=0;key<MAX_ROW;++key)
{
string val="val:";
for(int j=0;j<rand()%200+1;++j) // 最大で200文字のデータと仮定
{
val+= (char)(48+rand()%10); // アスキーコードで0から9の数字の文字を作る
}
table.at(key)=val;
}
return(0);
}
int insert_data_table(vector<Connection> &db_conn, vector<string> &table)
{
#pragma omp parallel for // OpenMP対応
for(int key=0;key<MAX_ROW;++key)
{
ostringstream ost;
Query query = db_conn.at(omp_get_thread_num()).query(); // 各スレッド用のコネクションを使う
query<<"INSERT INTO bench (mykey, value) VALUES ("<<key<<",'"<<table.at(key)<<"')";
ost<<"cannot insert test data("<<key<<","<<table.at(key)<<")";
if(query.execute()==false) Abort(ost.str());
}
return(0);
}
int main()
{
srand(0); // 同じ乱数を生成するために同じシードを使う
vector<string> table(MAX_ROW);
vector<Connection> conn(false);
conn.resize(atoi(getenv("OMP_NUM_THREADS"))); // 同時スレッド数の数だけコネクションを準備
for(int i=0;i<conn.size();++i)
{
if(conn[i].connect("test", "127.0.0.1", "nobody", "")!=true)
{
Abort("cannot connect db");
}
}
database_reset(conn[0]); // テーブルの初期化は一回でいいので
generate_data_table(table);
insert_data_table(conn, table);
return(0);
}このプログラムのコンパイルは,FreeBSDではこんな感じです.
> c++ mysql-test.cc -fopenmp -I/usr/local/mysql/include -I/usr/local/include/mysql++/ -L/usr/local/mysql/lib -L/usr/local/lib -lmysqlpp
まずMySQLで実行してみます.
> setenv OMP_NUM_THREADS 1 > time ./a.out 0.504u 0.376s 0:17.12 5.0% 34+1189k 0+0io 0pf+0w > setenv OMP_NUM_THREADS 10 > time ./a.out 0.624u 0.327s 0:08.29 11.3% 32+1136k 0+0io 0pf+0w
次,Drizzle行きます.
> setenv OMP_NUM_THREADS 1 > time ./a.out 0.536u 0.345s 0:17.08 5.0% 26+928k 0+0io 0pf+0w > setenv OMP_NUM_THREADS 10 > time ./a.out 0.560u 0.373s 0:07.27 12.7% 29+1031k 0+0io 0pf+0w
速度的には,ほぼ同じという結果が得られました.
どちらもスレッド数が1では約17秒,スレッド数が10では約7〜8秒でした.
特にDrizzleが高速だったということは無いですが,逆に言うと,Drizzleが既にMySQL相当の速度が出たと考えるべきでしょうか.
DBにinsertした内容は同一でした.
ただし,mysqldumpでDrizzleのダンプを取ろうとするとエラーが出てしまって,drizzledumpというプログラムを使って比べました.