LinkBenchのインストールと使用について

気づいたら1年以上書いてなかった。。。

最近は色々なPCI-E SSDベンチマークを取る機会が多くなっていて、tpcc-mysqlだと負荷不足な感じなのと、異なる傾向のI/O負荷の高いベンチマークを取ってみたかったので以前から気になっていたFacebook製のLinkBenchを使い始めています(LinkBenchのgithub)。
今回はベンチマーククライアントに使っているOSがCentOS5系だったのでCentOS5系でのインストール方法について記載します。基本的にはCentOS6系でも変わらないと思います。

またgithubに書かれている内容を元に、実際にやってみた内容をまとめています。

事前準備

Javamavenインストール及び設定

この辺はお好みでインストール場所とかは変更して下さい。
Javaは7以上が必要なようなのでCentOS5系ではyumからインストールしています。

$ sudo yum install java-1.7.0-openjdk java-1.7.0-openjdk-devel
$ wget http://ftp.riken.jp/net/apache/maven/maven-3/3.3.3/binaries/apache-maven-3.3.3-bin.tar.gz
$ tar zxf apache-maven-3.3.3-bin.tar.gz
$ sudo mv -i apache-maven-3.3.3 /usr/local/.
JAVA_HOMEの設定とmavenへのPATH登録

LinkBenchのインストールの際に必要になるので以下のように環境変数を設定してください。適宜.bash_profileとかに書いておく事が推奨です。

$ export JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64
$ export PATH=/usr/local/apache-maven-3.3.3/bin:$PATH

LinkBenchのインストール

例によってgitコマンドで取得してmvnコマンドでインストール(ビルド?)します。すみませんがmavenよく知りません。。。

$ git clone https://github.com/facebook/linkbench.git
$ cd linkbench
$ mvn clean package

試してないですが、テストを限定する場合

$ mvn clean package -P fast-test

テストをスキップする場合

$ mvn clean package -DskipTests

とするようです。

以下が出ればインストール成功みたいです。

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 07:29 min
[INFO] Finished at: 2015-05-13T01:59:05+09:00
[INFO] Final Memory: 80M/1758M
[INFO] ------------------------------------------------------------------------
実行確認
$ ./bin/linkbench
Using java at: /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
Did not select benchmark mode
usage: linkbench [-c <file>] [-csvstats <file>] [-csvstream <file>] [-D
       <property=value>] [-L <file>] [-l] [-r]
 -c <file>                       Linkbench config file
 -csvstats,--csvstats <file>     CSV stats output
 -csvstream,--csvstream <file>   CSV streaming stats output
 -D <property=value>             Override a config setting
 -L <file>                       Log to this file
 -l                              Execute loading stage of benchmark
 -r                              Execute request stage of benchmark
$

MySQLの準備

ベンチマークを行うハードウェアで動作するMySQLで以下のようにデータベース作成等、準備を行います。まずは以下を実行します。

create database linkdb;
use linkdb;

CREATE TABLE `linktable` (
  `id1` bigint(20) unsigned NOT NULL DEFAULT '0',
  `id2` bigint(20) unsigned NOT NULL DEFAULT '0',
  `link_type` bigint(20) unsigned NOT NULL DEFAULT '0',
  `visibility` tinyint(3) NOT NULL DEFAULT '0',
  `data` varchar(255) NOT NULL DEFAULT '',
  `time` bigint(20) unsigned NOT NULL DEFAULT '0',
  `version` int(11) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (link_type, `id1`,`id2`),
  KEY `id1_type` (`id1`,`link_type`,`visibility`,`time`,`id2`,`version`,`data`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 PARTITION BY key(id1) PARTITIONS 16;

CREATE TABLE `counttable` (
  `id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `link_type` bigint(20) unsigned NOT NULL DEFAULT '0',
  `count` int(10) unsigned NOT NULL DEFAULT '0',
  `time` bigint(20) unsigned NOT NULL DEFAULT '0',
  `version` bigint(20) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`,`link_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `nodetable` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `type` int(10) unsigned NOT NULL,
  `version` bigint(20) unsigned NOT NULL,
  `time` int(10) unsigned NOT NULL,
  `data` mediumtext NOT NULL,
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

続いてベンチマーク用のMySQLアカウントを作成します。リモートからベンチマークを実行する場合は適宜localhostを192.168.1.0/255.255.255.0とかに変更して下さい。

CREATE USER 'linkbench'@'localhost' IDENTIFIED BY 'パスワード';
GRANT ALL ON linkdb.* TO 'linkbench'@'localhost';

最小限の設定

config/FBWorkload.propertiesファイルで最小限の設定(接続情報)を記載します 。その他、負荷に関する設定も記述されています。
またconfig/FBWorkload.propertiesにはデータ量に関する設定も記述されています。

$ cp config/LinkConfigMysql.properties config/MyConfig.properties
$ vi config/MyConfig.properties
$ diff -U3 config/LinkConfigMysql.properties config/MyConfig.properties
--- config/LinkConfigMysql.properties   2015-05-13 01:42:23.000000000 +0900
+++ config/MyConfig.properties  2015-05-13 05:17:50.000000000 +0900
@@ -27,9 +27,9 @@
 nodestore = com.facebook.LinkBench.LinkStoreMysql

 # MySQL connection information
-host = yourhostname.here
-user = MySQLuser
-password = MySQLpass
+host = [IPアドレスorホストネーム]
+user = linkbench
+password = [パスワード]
 port = 3306
 # dbid: the database name to use
 dbid = linkdb
$

ベンチマーク用データのロード

以下コマンドでベンチマーク用のデータをロードします。
innodb_page_size=4kの場合、約12GBのデータが作成されます。

$ ./bin/linkbench -c config/MyConfig.properties -l

事前にMySQLに接続して以下を実行する事でロード時間の短縮が行えます。

use linkdb;
alter table linktable drop key `id1_type`;
set global innodb_flush_log_at_trx_commit = 2;
set global sync_binlog = 0;

ロードが終わったら以下コマンドを実行して環境を元に戻すのを忘れないで下さい。

set global innodb_flush_log_at_trx_commit = 1;
set global sync_binlog = 1;
alter table linktable add key `id1_type`
  (`id1`,`link_type`,`visibility`,`time`,`id2`,`version`,`data`);

INDEXも貼り直した状態で以下のファイルサイズで作成されました。

$ ls -lh /var/lib/mysql/linkdb/
total 12G
-rw-rw---- 1 mysql mysql 8.5K May 13 05:12 counttable.frm
-rw-rw---- 1 mysql mysql 584M May 13 05:30 counttable.ibd
-rw-rw---- 1 mysql mysql   61 May 13 05:12 db.opt
-rw-rw---- 1 mysql mysql 8.6K May 13 05:33 linktable.frm
-rw-rw---- 1 mysql mysql   88 May 13 05:33 linktable.par
-rw-rw---- 1 mysql mysql 400M May 13 05:33 linktable#P#p0.ibd
-rw-rw---- 1 mysql mysql 548M May 13 05:35 linktable#P#p10.ibd
-rw-rw---- 1 mysql mysql 300M May 13 05:35 linktable#P#p11.ibd
-rw-rw---- 1 mysql mysql 440M May 13 05:35 linktable#P#p12.ibd
-rw-rw---- 1 mysql mysql 364M May 13 05:35 linktable#P#p13.ibd
-rw-rw---- 1 mysql mysql 668M May 13 05:35 linktable#P#p14.ibd
-rw-rw---- 1 mysql mysql 376M May 13 05:36 linktable#P#p15.ibd
-rw-rw---- 1 mysql mysql 380M May 13 05:33 linktable#P#p1.ibd
-rw-rw---- 1 mysql mysql 676M May 13 05:33 linktable#P#p2.ibd
-rw-rw---- 1 mysql mysql 324M May 13 05:33 linktable#P#p3.ibd
-rw-rw---- 1 mysql mysql 416M May 13 05:33 linktable#P#p4.ibd
-rw-rw---- 1 mysql mysql 296M May 13 05:34 linktable#P#p5.ibd
-rw-rw---- 1 mysql mysql 832M May 13 05:34 linktable#P#p6.ibd
-rw-rw---- 1 mysql mysql 344M May 13 05:34 linktable#P#p7.ibd
-rw-rw---- 1 mysql mysql 432M May 13 05:34 linktable#P#p8.ibd
-rw-rw---- 1 mysql mysql 352M May 13 05:34 linktable#P#p9.ibd
-rw-rw---- 1 mysql mysql 8.5K May 13 05:26 nodetable.frm
-rw-rw---- 1 mysql mysql 3.6G May 13 05:31 nodetable.ibd
$

config/FBWorkload.properties の maxid1 = 200000001 にすると218GBのデータが作成されました。

$ du -sch /var/lib/mysql/linkdb/
218G    /var/lib/mysql/linkdb/
218G    total
$
$ ls -lh /var/lib/mysql/linkdb/
total 218G
-rw-rw---- 1 mysql mysql 8.5K May 13 05:43 counttable.frm
-rw-rw---- 1 mysql mysql  12G May 13 06:20 counttable.ibd
-rw-rw---- 1 mysql mysql   61 May 13 05:43 db.opt
-rw-rw---- 1 mysql mysql 8.6K May 13 16:35 linktable.frm
-rw-rw---- 1 mysql mysql   88 May 13 16:35 linktable.par
-rw-rw---- 1 mysql mysql 6.6G May 13 16:43 linktable#P#p0.ibd
-rw-rw---- 1 mysql mysql 6.0G May 13 18:17 linktable#P#p10.ibd
-rw-rw---- 1 mysql mysql  12G May 13 18:31 linktable#P#p11.ibd
-rw-rw---- 1 mysql mysql 5.4G May 13 18:37 linktable#P#p12.ibd
-rw-rw---- 1 mysql mysql 9.4G May 13 18:48 linktable#P#p13.ibd
-rw-rw---- 1 mysql mysql 5.9G May 13 18:54 linktable#P#p14.ibd
-rw-rw---- 1 mysql mysql  14G May 13 19:11 linktable#P#p15.ibd
-rw-rw---- 1 mysql mysql 6.0G May 13 16:50 linktable#P#p1.ibd
-rw-rw---- 1 mysql mysql 5.7G May 13 16:56 linktable#P#p2.ibd
-rw-rw---- 1 mysql mysql  18G May 13 17:17 linktable#P#p3.ibd
-rw-rw---- 1 mysql mysql 5.6G May 13 17:23 linktable#P#p4.ibd
-rw-rw---- 1 mysql mysql 9.9G May 13 17:34 linktable#P#p5.ibd
-rw-rw---- 1 mysql mysql 5.7G May 13 17:40 linktable#P#p6.ibd
-rw-rw---- 1 mysql mysql  13G May 13 17:55 linktable#P#p7.ibd
-rw-rw---- 1 mysql mysql 6.4G May 13 18:02 linktable#P#p8.ibd
-rw-rw---- 1 mysql mysql 8.0G May 13 18:11 linktable#P#p9.ibd
-rw-rw---- 1 mysql mysql 8.5K May 13 05:44 nodetable.frm
-rw-rw---- 1 mysql mysql  71G May 13 07:31 nodetable.ibd
$

LinkBenchの実行

以下コマンドでベンチマークを実行します。デフォルトでは200接続で負荷を掛ける事になります(requesters = 100だけど接続数は200のようでした)。
config/MyConfig.propertiesの requesters = 100 を編集する事で接続数は変更可能です。実行時にオプションとして渡す事も出来ます。

$ ./bin/linkbench -c config/MyConfig.properties -r

requestersを50として実行する場合は以下のようになります。

$ ./bin/linkbench -c config/MyConfig.properties -D requesters=50 -r

また、10分間のwarmupを行う場合は以下のようになります。設定ファイルではwarmup_time = 0でデフォルト0秒です。

$ ./bin/linkbench -c config/MyConfig.properties -D warmup_time=600 -r

スレッド毎にもレポートは出ますが、サマリーとしては以下のような出力になります。それぞれのレイテンシーについての出力もあります(時間は削除しています)。

[main]: ADD_NODE count = 1286123  p25 = [2,3]ms  p50 = [4,5]ms  p75 = [8,9]ms  p95 = [25,26]ms  p99 = [47,48]ms  max = 350.06ms  mean = 7.336ms
[main]: UPDATE_NODE count = 3680962  p25 = [2,3]ms  p50 = [4,5]ms  p75 = [9,10]ms  p95 = [27,28]ms  p99 = [48,49]ms  max = 419.252ms  mean = 8.255ms
[main]: DELETE_NODE count = 505534  p25 = [2,3]ms  p50 = [4,5]ms  p75 = [8,9]ms  p95 = [25,26]ms  p99 = [46,47]ms  max = 360.033ms  mean = 7.705ms
[main]: GET_NODE count = 6468958  p25 = [0.4,0.5]ms  p50 = [1,2]ms  p75 = [3,4]ms  p95 = [10,11]ms  p99 = [18,19]ms  max = 143.47ms  mean = 2.753ms
[main]: ADD_LINK count = 4493508  p25 = [4,5]ms  p50 = [7,8]ms  p75 = [20,21]ms  p95 = [55,56]ms  p99 = [90,91]ms  max = 896.368ms  mean = 15.965ms
[main]: DELETE_LINK count = 1495732  p25 = [0.5,0.6]ms  p50 = [1,2]ms  p75 = [6,7]ms  p95 = [39,40]ms  p99 = [79,80]ms  max = 609.526ms  mean = 7.77ms
[main]: UPDATE_LINK count = 4004540  p25 = [4,5]ms  p50 = [7,8]ms  p75 = [20,21]ms  p95 = [53,54]ms  p99 = [89,90]ms  max = 902.957ms  mean = 15.641ms
[main]: COUNT_LINK count = 2440215  p25 = [0.2,0.3]ms  p50 = [0.4,0.5]ms  p75 = [1,2]ms  p95 = [6,7]ms  p99 = [13,14]ms  max = 113.011ms  mean = 1.335ms
[main]: MULTIGET_LINK count = 263447  p25 = [0.2,0.3]ms  p50 = [0.3,0.4]ms  p75 = [0.7,0.8]ms  p95 = [4,5]ms  p99 = [12,13]ms  max = 442.304ms  mean = 1.144ms
[main]: GET_LINKS_LIST count = 25360981  p25 = [0.2,0.3]ms  p50 = [0.4,0.5]ms  p75 = [0.7,0.8]ms  p95 = [4,5]ms  p99 = [13,14]ms  max = 2795.329ms  mean = 1.21ms
[main]: REQUEST PHASE COMPLETED. 50000000 requests done in 2461 seconds. Requests/second = 20311

ベンチマーク後のファイルサイズは以下のようになりました。

$ du -sch /var/lib/mysql/linkdb/
246G    /var/lib/mysql/linkdb/
$
$ ls -lh /var/lib/mysql/linkdb/
total 246G
-rw-rw---- 1 mysql mysql 8.5K May 13 05:43 counttable.frm
-rw-rw---- 1 mysql mysql  13G May 14 03:36 counttable.ibd
-rw-rw---- 1 mysql mysql   61 May 13 05:43 db.opt
-rw-rw---- 1 mysql mysql 8.6K May 13 16:35 linktable.frm
-rw-rw---- 1 mysql mysql   88 May 13 16:35 linktable.par
-rw-rw---- 1 mysql mysql 7.7G May 14 03:36 linktable#P#p0.ibd
-rw-rw---- 1 mysql mysql 7.1G May 14 03:36 linktable#P#p10.ibd
-rw-rw---- 1 mysql mysql  14G May 14 03:36 linktable#P#p11.ibd
-rw-rw---- 1 mysql mysql 6.4G May 14 03:36 linktable#P#p12.ibd
-rw-rw---- 1 mysql mysql  12G May 14 03:36 linktable#P#p13.ibd
-rw-rw---- 1 mysql mysql 7.0G May 14 03:36 linktable#P#p14.ibd
-rw-rw---- 1 mysql mysql  16G May 14 03:36 linktable#P#p15.ibd
-rw-rw---- 1 mysql mysql 7.0G May 14 03:36 linktable#P#p1.ibd
-rw-rw---- 1 mysql mysql 6.8G May 14 03:36 linktable#P#p2.ibd
-rw-rw---- 1 mysql mysql  21G May 14 03:36 linktable#P#p3.ibd
-rw-rw---- 1 mysql mysql 6.7G May 14 03:36 linktable#P#p4.ibd
-rw-rw---- 1 mysql mysql  12G May 14 03:36 linktable#P#p5.ibd
-rw-rw---- 1 mysql mysql 6.8G May 14 03:36 linktable#P#p6.ibd
-rw-rw---- 1 mysql mysql  16G May 14 03:36 linktable#P#p7.ibd
-rw-rw---- 1 mysql mysql 7.5G May 14 03:36 linktable#P#p8.ibd
-rw-rw---- 1 mysql mysql 9.5G May 14 03:36 linktable#P#p9.ibd
-rw-rw---- 1 mysql mysql 8.5K May 13 05:44 nodetable.frm
-rw-rw---- 1 mysql mysql  73G May 14 03:36 nodetable.ibd
$

終わりに

その他色々細かい設定もあるみたいです。今の所はほぼ初期の設定で使用していますがデフォルトのrequesters = 100だと相当の負荷がかかります。HDDでは5とかに減らす事をお勧めします(SATAのHDDとか100で負荷かけたらすぐ壊れそう)。感覚的にはSSDなら32ぐらいから試すと良いと思います。

ベンチマークの結果は所詮目安ですが、チューニングの勉強にもなるので色々やってみると面白いですよ。