mroongaを使った、高速な対訳検索&ダウンロードシステムについて

発表の資料

発表時の資料はこちらになります。

mroongaを使った、高速な対訳検索&ダウンロードシステムについて

追試の情報

全文検索エンジンgroongaを囲む夕べ3が終了した後、発表者の磯部さんが発表内容のシステムで追試の実験を行い、結果をご送付いただきました。それをまとめたものを次のセクションに掲載しています。

発表時の資料と合わせてご覧ください。

Swapによって検索速度が変化するかどうかの検証

発表で話した同じ型のキューブPC(HDDはSATA3)の別マシンにて、HDD上に単一テーブルとしてmroongaのDBを構成しました。そのDBに対してSQLを1つ実行したところ、19672件取得するのに6m41.472sかかりました。発表で紹介したシステム(テーブルを8分割した場合)だと、1秒ちょっとです。

この時実行したSQLの概要は次のようになっています。

  • 英語、又は日本語の「単語又はフレーズ一致」でありその英語欄と日本語欄にはmroongaのインデックスが張ってある
  • その他のフィールドはselectの出力には含まれるが、where句では指定していない
  • 「blue」というありふれた単語で検索したので大量にヒットした

このSQLの実行途中に、仮想メモリの状況を調べるために次のコマンドを実行しました。

$ vmstat 5 -S m

これは、5秒間隔でサンプリングし、単位はMBで表示することを示しています。このコマンドの結果は下記のようになりました。

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  1      0  17638      3  15021    0    0  2603     2   65   57  0  3 94  3  0
 0  1      0  17470      3  15188    0    0 32540     0  368  997  0  0 88 12  0
 0  1      0  17338      3  15320    0    0 25758     0  284  768  0  0 88 12  0
 0  1      0  17214      3  15443    0    0 24138     0  265  740  0  0 88 12  0
 0  1      0  17087      3  15569    0    0 24658     0  269  752  0  0 88 12  0
 0  1      0  16940      3  15716    0    0 28556     0  308  853  0  0 88 12  0
 0  1      0  16800      3  15856    0    0 27324     0  312  850  0  0 88 12  0
    

「bi」(ディスクから読み込んだ量)の欄を見ると、物凄い勢いでDiskを読んでいることがわかります。今回のPCは8CPUですので、「wa」欄(I/O待ち)の12%は、1CPU分フルに発生している状況です。

この時のメモリの状況です。

$ free -m
total used free shared buffers cached
Mem: 32110 30820 1289 0 2 27841
-/+ buffers/cache: 2977 29132
Swap: 1998 0 1998
  

Swapは全く発生していません。よって、Swapは関係なく、単純にディスクの読み込みで遅いことがわかります。

つまり、BI的に、一括で大量のデータを取得する場合には、プレゼンのように、データをRAM-Disk上に置くのが有効である事が判ります。第1システムでのSWAPがある状況だと遅いと言う推測は外れでした。

また、twitterでのつぶやきを見ると、5千万件以下の場合はテーブルのパーティショニングは必要ないかもしれない、ということなので、テーブルの分割は必要ないかもしれません。

テーブルを分割しない場合の速度

発表では8分割していたテーブルを1つに纏めたもので更に追試しました。

※正確には、日本語部分と英語部分が標準化されたデータなので英語と日本語のフィールド名と検索結果の件数が若干異なります。

下記が、今回の1つに纏まったテーブルに対する検証用スクリプトです。

HDD上のDBに対するスクリプト:

$ cat test.sh
export DB=TAIYAKU_DB
echo 'select * from TAIYAKU_DATA where match(EN_TEXT) against
('\''blue'\'' in boolean mode)' | do_sql
  

RAM-Disk上のDBに対するスクリプト:

$ cat test_u.sh
export DB=TAIYAKU_DB_Unified
echo 'select * from TAIYAKU_DATA where match(EN_TEXT_JUNKANZEN_ICCHI)
against ('\''blue'\'' in boolean mode)' | do_sql
  

上記スクリプト内にある、"do_sql"は自作のSQLラッパーで、環境変数のHOSTで接続先IPを、DBでデータベース名を指定してSQLを実行します。また、TAIYAKU_DBはHDD上のDBで、TAIYAKU_DB_UnifiedはRAM-Disk上のDBです。両方のDBとも、件数は下記のように同一です。

$ env DB=TAIYAKU_DB count TAIYAKU_DATA
35201206
$ env DB=TAIYAKU_DB_Unified count TAIYAKU_DATA
35201206
  

上記の"count"は、先ほどの"do_sql"の更なるラッパーで、件数を取得します。これらスクリプトの実行速度と、検索結果の行数は下記のとおりです。

HDD上のDBに対する実行:

$ time bash test_u.sh > /tmp/a
real 0m0.662s
user 0m0.147s
sys 0m0.017s
  

検索結果:

$ wc -l /tmp/a
19996 /tmp/a
  

RAM-Disk上のDBに対する実行:

$ time bash test.sh > /tmp/b
real 4m44.247s
user 0m0.169s
sys 0m0.026s
  

検索結果:

$ wc -l /tmp/b
19672 /tmp/b
  

RAM-DiskへのDBの設置

HDD上の、/var/lib/mysql/mroonga.data/に本来のmroongaファイルが格納されています。

$ cd /var/lib/mysql/mroonga.data/
$ ls -l
(中略)
drwx------ 2 mysql mysql 4096 12月 6 12:52 2012 TAIYAKU_DB_Unified
(中略)
  

このTAIYAKU_DB_Unifiedが本来のmroongaファイルです。PCの再起動などを行った時は、下記のようにしてRAM-DiskにTAIYAKU_DB_Unifiedをコピーします。

cd /var/lib/mysql/mroonga.data/
cp -rp TAIYAKU_DB_Unified /dev/shm/mysql/
  

また、最初にRAM-Disk上のDBからHDD上にシンボリックリンクを作成する時は、下記のようにしました。

$ cd /var/lib/mysql/mroonga.data/
$ for F in $(ls /dev/shm/mysql/TAIYAKU_DB_Unified/TAIYAKU_DB_Unified.mrn*); do ln -s $F;
done
  

再起動後も、シンボリックリンクは残っているので次のコマンドを実行してから上記のコピーをするだけです。

$service mysqld stop