ウチではかつてはTritonn全盛、今はmroonga全盛な「MySQL de FullTextSearch」が大好きな感じでやっています。Sphinxとか誰か手を出さないかなぁと思いつつ、いい加減MySQL de FTSから足を洗って全文検索ライブラリはMySQLとは連携させないでやろうぜ、というのもあったりします。
そこで取り敢えず現状の洗い出し(?)の一環として、mroongaのストレージサイズをぼんやりと考えてみることにします。
というか運用している分にはこれがキツい。
インデックス用のmrnファイルは(tokenBigramなせいもあって)データサイズに対して線形に増えるので、ストレージ容量と、あとそれをキャッシュするだけのメモリ増設がもうままならない。
実際どれくらい食うのかを取り敢えず測ってみる。
サンプルデータはTwitterのツイート履歴。
ただし全文検索が試したいだけだったり、カラムをもろもろ列挙したりするのがものすごく面倒だったのでテーブル構成はすごく手抜きな感じで。
mysql55> CREATE TABLE myisam.tweet ( tweet_id BIGINT UNSIGNED PRIMARY KEY, timestamp TIMESTAMP NOT NULL DEFAULT 0, text TEXT) Engine = MyISAM; Query OK, 0 rows affected (0.03 sec) mysql55> CREATE TABLE mroonga_storage.tweet ( tweet_id BIGINT UNSIGNED PRIMARY KEY, timestamp TIMESTAMP NOT NULL DEFAULT 0, text TEXT) Engine = mroonga; Query OK, 0 rows affected (0.07 sec) mysql55> CREATE TABLE mroonga_wrapper.tweet ( tweet_id BIGINT UNSIGNED PRIMARY KEY, timestamp TIMESTAMP NOT NULL DEFAULT 0, text TEXT) Engine = mroonga COMMENT = 'Engine "MyISAM"'; Query OK, 0 rows affected (0.09 sec)
MyISAM、ストレージモード、ラッパーモードでそれぞれ作る。
mroongaはデータベース単位でmrnファイルを作ってしまうのでデータベースも分けておく。
mysql55> SHOW TABLE STATUS FROM myisam\G *************************** 1. row *************************** Name: tweet Engine: MyISAM Version: 10 Row_format: Dynamic Rows: 0 Avg_row_length: 0 Data_length: 0 Max_data_length: 281474976710655 Index_length: 1024 Data_free: 0 Auto_increment: NULL Create_time: 2013-08-19 19:39:02 Update_time: 2013-08-19 19:39:02 Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.01 sec) mysql55> SHOW TABLE STATUS FROM mroonga_storage\G *************************** 1. row *************************** Name: tweet Engine: mroonga Version: 10 Row_format: Dynamic Rows: 0 Avg_row_length: 0 Data_length: 4526080 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: NULL Update_time: NULL Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.01 sec) mysql55> SHOW TABLE STATUS FROM mroonga_wrapper\G *************************** 1. row *************************** Name: tweet Engine: mroonga Version: 10 Row_format: Dynamic Rows: 0 Avg_row_length: 0 Data_length: 0 Max_data_length: 0 Index_length: 1024 Data_free: 0 Auto_increment: NULL Create_time: NULL Update_time: 2013-08-19 19:39:09 Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: Engine "MyISAM" 1 row in set (0.01 sec) $ ls -l myisam/* | tee >(awk '{i+=$5}END{print i}') -rw-rw---- 1 mysql mysql 61 8月 19 19:38 2013 myisam/db.opt -rw-rw---- 1 mysql mysql 0 8月 19 19:39 2013 myisam/tweet.MYD -rw-rw---- 1 mysql mysql 1024 8月 19 19:39 2013 myisam/tweet.MYI -rw-rw---- 1 mysql mysql 8638 8月 19 19:39 2013 myisam/tweet.frm 9723 $ ls -l mroonga_storage* | tee >(awk '{i+=$5}END{print i}') -rw-rw---- 1 mysql mysql 4096 8月 19 19:39 2013 mroonga_storage.mrn -rw-rw---- 1 mysql mysql 12857344 8月 19 19:39 2013 mroonga_storage.mrn.0000000 -rw-rw---- 1 mysql mysql 4243456 8月 19 19:39 2013 mroonga_storage.mrn.0000103 -rw-rw---- 1 mysql mysql 4096 8月 19 19:39 2013 mroonga_storage.mrn.0000104 -rw-rw---- 1 mysql mysql 4096 8月 19 19:39 2013 mroonga_storage.mrn.0000105 -rw-rw---- 1 mysql mysql 274432 8月 19 19:39 2013 mroonga_storage.mrn.0000106 -rw-rw---- 1 mysql mysql 1048576 8月 19 19:39 2013 mroonga_storage.mrn.001 mroonga_storage: 合計 16 -rw-rw---- 1 mysql mysql 61 8月 19 19:38 2013 db.opt -rw-rw---- 1 mysql mysql 8638 8月 19 19:39 2013 tweet.frm 18444795 $ ls -l mroonga_wrapper* | tee >(awk '{i+=$5}END{print i}') -rw-rw---- 1 mysql mysql 4096 8月 19 19:39 2013 mroonga_wrapper.mrn -rw-rw---- 1 mysql mysql 12857344 8月 19 19:39 2013 mroonga_wrapper.mrn.0000000 -rw-rw---- 1 mysql mysql 65536 8月 19 19:39 2013 mroonga_wrapper.mrn.0000103 -rw-rw---- 1 mysql mysql 1048576 8月 19 19:39 2013 mroonga_wrapper.mrn.001 mroonga_wrapper: 合計 20 -rw-rw---- 1 mysql mysql 61 8月 19 19:38 2013 db.opt -rw-rw---- 1 mysql mysql 0 8月 19 19:39 2013 tweet.MYD -rw-rw---- 1 mysql mysql 1024 8月 19 19:39 2013 tweet.MYI -rw-rw---- 1 mysql mysql 8638 8月 19 19:39 2013 tweet.frm 13985275
mroonga_storage, mroonga_wrapperの差とmroonga_storageのSHOW TABLE STATUSの結果から察するに、.mrn.0000103が.MYDファイルみたいな扱いになるんだろうか。
LOAD DATA INFILEで1万ツイートほど流し込んでみる。
mysql55> LOAD DATA INFILE '/tmp/tweets.csv' INTO TABLE tweet FIELDS TERMINATED BY ',' ENCLOSED BY '"' IGNORE 1 LINES (tweet_id, @dummy, @dummy, @dummy, @dummy, timestamp, @dummy, text, @dummy); Query OK, 10045 rows affected, 10089 warnings (0.25 sec) Records: 10045 Deleted: 0 Skipped: 0 Warnings: 10089
timestampカラムのデータを切り詰めたとかフィールドの数が合わないってワーニングが出てたけど大勢に影響がないので気にしない。
mysql55> SHOW TABLE STATUS FROM myisam\G *************************** 1. row *************************** Name: tweet Engine: MyISAM Version: 10 Row_format: Dynamic Rows: 10045 Avg_row_length: 125 Data_length: 1263404 Max_data_length: 281474976710655 Index_length: 217088 Data_free: 0 Auto_increment: NULL Create_time: 2013-08-19 19:39:02 Update_time: 2013-08-19 19:41:06 Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec) mysql55> SHOW TABLE STATUS FROM mroonga_storage\G *************************** 1. row *************************** Name: tweet Engine: mroonga Version: 10 Row_format: Dynamic Rows: 10045 Avg_row_length: 0 Data_length: 46469120 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: NULL Update_time: NULL Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec) mysql55> SHOW TABLE STATUS FROM mroonga_wrapper\G *************************** 1. row *************************** Name: tweet Engine: mroonga Version: 10 Row_format: Dynamic Rows: 10045 Avg_row_length: 125 Data_length: 1263404 Max_data_length: 0 Index_length: 217088 Data_free: 0 Auto_increment: NULL Create_time: NULL Update_time: 2013-08-19 19:41:19 Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: Engine "MyISAM" 1 row in set (0.00 sec) $ ls -l myisam/* | tee >(awk '{i+=$5}END{print i}') -rw-rw---- 1 mysql mysql 61 8月 19 19:38 2013 myisam/db.opt -rw-rw---- 1 mysql mysql 1263404 8月 19 19:41 2013 myisam/tweet.MYD -rw-rw---- 1 mysql mysql 217088 8月 19 19:41 2013 myisam/tweet.MYI -rw-rw---- 1 mysql mysql 8638 8月 19 19:39 2013 myisam/tweet.frm 1489191 $ ls -l mroonga_storage* | tee >(awk '{i+=$5}END{print i}') -rw-rw---- 1 mysql mysql 4096 8月 19 19:41 2013 mroonga_storage.mrn -rw-rw---- 1 mysql mysql 12857344 8月 19 19:39 2013 mroonga_storage.mrn.0000000 -rw-rw---- 1 mysql mysql 8437760 8月 19 19:41 2013 mroonga_storage.mrn.0000103 -rw-rw---- 1 mysql mysql 4198400 8月 19 19:41 2013 mroonga_storage.mrn.0000104 -rw-rw---- 1 mysql mysql 4198400 8月 19 19:41 2013 mroonga_storage.mrn.0000105 -rw-rw---- 1 mysql mysql 29634560 8月 19 19:41 2013 mroonga_storage.mrn.0000106 -rw-rw---- 1 mysql mysql 1048576 8月 19 19:39 2013 mroonga_storage.mrn.001 mroonga_storage: 合計 16 -rw-rw---- 1 mysql mysql 61 8月 19 19:38 2013 db.opt -rw-rw---- 1 mysql mysql 8638 8月 19 19:39 2013 tweet.frm 60387835 $ ls -l mroonga_wrapper* | tee >(awk '{i+=$5}END{print i}') -rw-rw---- 1 mysql mysql 4096 8月 19 19:39 2013 mroonga_wrapper.mrn -rw-rw---- 1 mysql mysql 12857344 8月 19 19:39 2013 mroonga_wrapper.mrn.0000000 -rw-rw---- 1 mysql mysql 65536 8月 19 19:39 2013 mroonga_wrapper.mrn.0000103 -rw-rw---- 1 mysql mysql 1048576 8月 19 19:39 2013 mroonga_wrapper.mrn.001 mroonga_wrapper: 合計 1464 -rw-rw---- 1 mysql mysql 61 8月 19 19:38 2013 db.opt -rw-rw---- 1 mysql mysql 1263404 8月 19 19:41 2013 tweet.MYD -rw-rw---- 1 mysql mysql 217088 8月 19 19:41 2013 tweet.MYI -rw-rw---- 1 mysql mysql 8638 8月 19 19:39 2013 tweet.frm 15464743
更新時刻やファイルサイズからして、.mrnと.mrn.000000はなんかテーブル情報持ってて、.mrn.00010x(から連番になるんだろう)ファイルがデータ本体ぽい。足すとData_lengthっぽくなるし。
MyISAMのテーブルはフルテキストインデックス作る気がないのでここまでとして、mroonga_storageとmroonga_wrapperでそれぞれインデックスを作ってみる。
mysql55> ALTER TABLE mroonga_storage.tweet ADD FULLTEXT KEY (text) COMMENT 'parser "TokenBigram"'; Query OK, 0 rows affected (0.48 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql55> ALTER TABLE mroonga_wrapper.tweet ADD FULLTEXT KEY (text) COMMENT 'parser "TokenBigram"'; Query OK, 10045 rows affected (1.18 sec) Records: 10045 Duplicates: 0 Warnings: 0 mysql55> SHOW TABLE STATUS FROM mroonga_storage\G *************************** 1. row *************************** Name: tweet Engine: mroonga Version: 10 Row_format: Dynamic Rows: 10045 Avg_row_length: 0 Data_length: 46469120 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: NULL Update_time: NULL Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec) mysql55> SHOW TABLE STATUS FROM mroonga_wrapper\G *************************** 1. row *************************** Name: tweet Engine: mroonga Version: 10 Row_format: Dynamic Rows: 10045 Avg_row_length: 125 Data_length: 1263404 Max_data_length: 0 Index_length: 217088 Data_free: 0 Auto_increment: NULL Create_time: NULL Update_time: 2013-08-19 19:45:54 Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: Engine "MyISAM" 1 row in set (0.00 sec) $ ls -l mroonga_storage* | tee >(awk '{i+=$5}END{print i}') -rw-rw---- 1 mysql mysql 4096 8月 19 19:45 2013 mroonga_storage.mrn -rw-rw---- 1 mysql mysql 17051648 8月 19 19:45 2013 mroonga_storage.mrn.0000000 -rw-rw---- 1 mysql mysql 8437760 8月 19 19:41 2013 mroonga_storage.mrn.0000103 -rw-rw---- 1 mysql mysql 4198400 8月 19 19:41 2013 mroonga_storage.mrn.0000104 -rw-rw---- 1 mysql mysql 4198400 8月 19 19:41 2013 mroonga_storage.mrn.0000105 -rw-rw---- 1 mysql mysql 29634560 8月 19 19:41 2013 mroonga_storage.mrn.0000106 -rw-rw---- 1 mysql mysql 8437760 8月 19 19:45 2013 mroonga_storage.mrn.0000107 -rw-rw---- 1 mysql mysql 2134016 8月 19 19:45 2013 mroonga_storage.mrn.0000108 -rw-rw---- 1 mysql mysql 8392704 8月 19 19:45 2013 mroonga_storage.mrn.0000108.c -rw-rw---- 1 mysql mysql 1048576 8月 19 19:45 2013 mroonga_storage.mrn.001 mroonga_storage: 合計 16 -rw-rw---- 1 mysql mysql 61 8月 19 19:38 2013 db.opt -rw-rw---- 1 mysql mysql 8638 8月 19 19:45 2013 tweet.frm 83546619 $ ls -l mroonga_wrapper* | tee >(awk '{i+=$5}END{print i}') -rw-rw---- 1 mysql mysql 4096 8月 19 19:45 2013 mroonga_wrapper.mrn -rw-rw---- 1 mysql mysql 17051648 8月 19 19:45 2013 mroonga_wrapper.mrn.0000000 -rw-rw---- 1 mysql mysql 16842752 8月 19 19:45 2013 mroonga_wrapper.mrn.0000104 -rw-rw---- 1 mysql mysql 8437760 8月 19 19:45 2013 mroonga_wrapper.mrn.0000105 -rw-rw---- 1 mysql mysql 7639040 8月 19 19:45 2013 mroonga_wrapper.mrn.0000106 -rw-rw---- 1 mysql mysql 12587008 8月 19 19:45 2013 mroonga_wrapper.mrn.0000106.c -rw-rw---- 1 mysql mysql 1048576 8月 19 19:45 2013 mroonga_wrapper.mrn.001 mroonga_wrapper: 合計 1464 -rw-rw---- 1 mysql mysql 61 8月 19 19:38 2013 db.opt -rw-rw---- 1 mysql mysql 1263404 8月 19 19:45 2013 tweet.MYD -rw-rw---- 1 mysql mysql 217088 8月 19 19:45 2013 tweet.MYI -rw-rw---- 1 mysql mysql 8638 8月 19 19:45 2013 tweet.frm 65100071
SHOW TABLE STATUSには計上されないんだね。。容量の増加量はストレージモードで23MiB, ラッパーモードで48MiBくらい。
TokenBigramのトークン数はフルテキスト文字数とイコールで、SUM(CHARACTER_LENGTH(text))で取ったら504972だったので、トークンは概算で50万とする。アルファベットはまとめて1つのトークンにするとかそういうのは取り敢えず今は考えない。
⇒本当はSUM(CHARACTER_LENGTH(text) - 1)になるかと思ったんだけど、ならないみたい。
⇒http://groonga.org/docs/spec/search.html
1トークンあたりのサイズは(2 * charset + PRIMARY KEY SIZE)くらいかなと期待すると、utf8は1文字3バイトでPRIMARY KEYがBIGINTの8バイトで16バイト。
単純に掛け算すると8MiBくらいが期待だったんだけど、とてもそんなもんじゃ済んでない。単純にLOAD DATAしただけでも60MiB食うような感じだから、内部的に色々情報を持っててこれじゃ済まないってことなんだろうけど。
取り敢えず思ったより行くよね、というところに止めておいて他の何かで追試したい。というか、してくる。
TokenMecabでどのくらい減らせるかも調べたい。。
0 件のコメント :
コメントを投稿