2007年02月28日

Senna 1.0.0がリリースされたよ!

遂にSennaの1.0.0が出ましたよ!
プレスリリースによると

●メジャーバージョン(1.0.0)リリースについて

Senna1.0.0では転置インデックスの格納形式を改善し、更新/検索速度を損ねる
ことなくサイズを最大で従来比70%程度まで圧縮することに成功しました。この
ため、従来よりも大規模な文書を1台のサーバで管理することが可能となりました。

という事なので早速wktkしながらinstallしました。

色々考えるのがめんどくさかったので、動いてる環境にsennaとmysqlを順番にmake installしてmysql restartです。

早速indexを作り直してみると。。。。

-rw-rw----  1 mysql mysql 1.0K  21:05 SEARCH_DATA.MYI
-rw-rw---- 1 mysql mysql 263M 21:05 SEARCH_DATA.000.SEN.i.c
-rw-rw---- 1 mysql mysql 31M 21:05 SEARCH_DATA.000.SEN.i
-rw-rw---- 1 mysql mysql 45M 21:03 SEARCH_DATA.000.SEN.l
-rw-rw---- 1 mysql mysql 8.1M 20:56 SEARCH_DATA.000.SEN
-rw-rw---- 1 mysql mysql 426M 20:56 SEARCH_DATA.MYD
-rw-rw---- 1 mysql mysql 8.5K 20:56 SEARCH_DATA.frm
-rw-rw---- 1 mysql mysql 1.0K 17:01 SEARCH_DATA_senna_r327.MYI
-rw-rw---- 1 mysql mysql 325M 17:01 SEARCH_DATA_senna_r327.000.SEN.i.c
-rw-rw---- 1 mysql mysql 31M 17:01 SEARCH_DATA_senna_r327.000.SEN.i
-rw-rw---- 1 mysql mysql 85M 16:59 SEARCH_DATA_senna_r327.000.SEN.l
-rw-rw---- 1 mysql mysql 8.1M 16:51 SEARCH_DATA_senna_r327.000.SEN
-rw-rw---- 1 mysql mysql 426M 16:51 SEARCH_DATA_senna_r327.MYD
-rw-rw---- 1 mysql mysql 8.5K 16:51 SEARCH_DATA_senna_r327.frm
_senna_r327って付いてるのが過去の物(0.8.0で作ったindex)で、上の方が1.0.0で作ったindexです。
本当にサイズ圧縮されてる!
今のところ漏れとか不具合っぽいのがないのでいい感じです。
どのようにしてサイズ削減を行ったかにもよりますが、サイズが小さいと細かい所でパフォーマンスも上がりそうな予感です。

そしてsennaのソースを久しぶりに見てみたら気になる所がいくつか。
mysql-4.0.27.senna.diffのsql/sql_yacc.yyを弄ってる箇所に

+       | ULONG_NUM { $1 < 65536 ? $$=((ulonglong)$1) << 32 : $$=$1; };
という処理が。
これはきっとUSING NGRAMとかの拡張クエリの部分を実装してる所だと思うんですが、ここに数値を直接指定できるようになってるっぽいんですよね。USING 97342482みたいに。
で、このUSINGのパラメータはMI_INFOのsenna_flagに入るっぽく、同patchのft_sen_index_addが実装されてる所辺りに
+#define SECTIONALIZE 0x00080000
ってあって
+  if (info->s->keyinfo[keynr].senna_flags & SECTIONALIZE) {
+ FT_SEG_ITERATOR ftsi;
+ uint len = 0;
+ unsigned int section;
+ sen_values *values;
+ _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+ while (_mi_ft_segiterator(&ftsi)) {
+ if (ftsi.pos) {
+ if (ftsi.len > 1048576) { sen_log("ft_sen_index_add: ftsi.len=%d", ftsi.len); }
+ if (ftsi.len > len) { len = ftsi.len; }
+ }
+ }
+ if (!len) { return -1; }
+ _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+ section = 1;
+ while (_mi_ft_segiterator(&ftsi)) {
+ if (ftsi.pos) {
+ values = sen_values_open();
+ sen_values_add(values, ftsi.pos, ftsi.len, 0);
+ sen_index_update(info->s->keyinfo[keynr].senna, &pos, section, NULL, values);
+ sen_values_close(values);
+ }
+ section++;
+ }
+ return 0;
+ } else {
みたいな処理が。

sen_values_*ってのは段落云々のAPIだから、mysqlバインディングのドキュメントに無い実装があるっぽいかもしれません。
多分複数のフィールドを一つの塊として扱えるんじゃないのかなぁ。良くわからないけど。


開発ロードマップを見るとストレージ機能の実装が有るそうなので、こちらもwktkです。

Posted by Yappo at 05:49 | Comments (1) | TrackBack

2005年11月27日

senna+mysql落ち着きました

中の人のアドバイスもあったおかげでメモリ消費量を抑えることが出来ました。
現在は、通常通り安定してます。
適切に動かしてればsenna+MySQLは超安定してますから。ほんとに。

インデックスファイル

.sen.iファイルの初期サイズ
デフォルトでは130MBを確保しますが、設定ファイル(/var/senna/senna.conf)に、

INITIAL_N_SEGMENTS 数値のように数値を指定すると、

数値 * 256KBのサイズが確保されるようになります。

ただし、INITIAL_N_SEGMENTSの値を小さく設定するほど、更新処理の速度が低下しますので、デフォルト値よりも極端に小さい値を設定しない方が無難です。(デフォルト値は512です)


これを、128にしました。
デフォだとSEN.iに130MBくらい取られるけど、38MB位まで落とし込みました。
indexerの性能よりも動かないとしょうがないしね。
DBに使用するファイルサイズも半分程度になりました。

ただし、当然なんですが

インデックスのサイズ
hoge.SEN.iファイルはインデックス作成時に固定サイズを確保しますが、その後文書を大量に登録するとインデックスファイルの総サイズは、単語インデックスなら文書の賞味サイズの1.3倍程度、 n-gramインデックスなら文書の賞味サイズの2.5倍程度になります。

って事なので、データサイズが増えると結局メモリを食うという感じなのかなんなのか
メモリ消費量はINITIAL_N_SEGMENTSの値に影響するのかSEN.iファイルサイズに影響するのか、まだ分かってませんです。


1GB位のデータを1テーブルでfulltextしてたんだけど、1クエリあたり0.3秒もかかって使い物にならなかったの。
どうして使い物にならないかというと、1queryあたり10回sennaにクエリを投げなきゃいけなくて実質3秒もかかる感じだった。
そんなわけでテーブルを分割しまくって数十倍くらいパフォーマンス上がったところで、今回の現象に遭遇したと言う訳。

word indexだけmmapして、wordとdocidの対応表はmmapしないでキャッシュはOSに任せてしまう方式に改造したら
メモリ食わないけど、やっぱ劇遅になるのかなぁ。

今後index size増やす方向にもってくから、どうにかしないと。
てか複数台構成にしろって話。

Posted by Yappo at 13:52 | Comments (0) | TrackBack

2005年11月26日

senna+MySQLでメモリ食いすぎて落ちる

急にMySQLが落ちるようになってしまった。
というのも、sennaのfulltext indexを張ったテーブルを25個ほど持つようにして、総データ量(MYD/SEN含む)が4G近くの構成にしてからだ。

topを抜粋するとこんな感じで

Mem:   4151320k total,  4056728k used,    94592k free,    55916k buffers
Swap: 4192924k total, 144k used, 4192780k free, 3831344k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17800 mysql 15 0 2550m 911m 850m S 0.0 22.5 3:02.22 mysqld


だいたいVIRT が3Gを超えると
mysqld got signal 11;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help diagnose
the problem, but since we have already crashed, something is definitely wrong
and this may fail.

key_buffer_size=134217728
read_buffer_size=4190208
max_used_connections=16
max_connections=500
threads_connected=11
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = 2078764 K
bytes of memory
Hope that's ok; if not, decrease some variables in the equation.


となってしまう・・・
スタックトレースすると
0x規制 handle_segfault + 553
0x規制 (?)
(nil)
0xd規制 (?)
0xd規制 (?)
0x規制 ft_boolean_reinit_search + 306
0x規制 _ZN9ha_myisam7ft_initEv + 33
0x規制 _Z18join_ft_read_firstP13st_join_table + 21
0x規制 _Z10sub_selectP4JOINP13st_join_tableb + 87
0x規制 _Z9do_selectP4JOINP4ListI4ItemEP8st_tableP9Procedure + 210
0x規制 _Z12mysql_selectP3THDP13st_table_listR4ListI4ItemEPS4_P8st_orderS9_S7_S9_mP13select_result + 9874
0x規制 _Z13handle_selectP3THDP6st_lexP13select_result + 133
0x規制 _Z21mysql_execute_commandv + 18685
0x規制 _Z11mysql_parseP3THDPcj + 320
0x規制 _Z16dispatch_command19enum_server_commandP3THDPcj + 2712
0x規制 handle_one_connection + 1392
0x規制 (?)
0x規制 (?)

って感じ

一回だけGot Error 12が出てたので、メモリ食いすぎが原因だろうけど

なんだろうなぁ、sennaって際限なくデータをmmapとかキャッシュするようにしてるのかなぁ…
gdbしようにも、再発させるのに時間が必要なのと検証マシンが用意できないので調査不能。
そもそもsennaに由来する事象なのかもわからんからsenna-devにも投げられんし、そもそも投げるに値する情報もまだナス

ボスケテ

追記:該当のテーブルを使わないようにしたら、メモリ食いつぶすことがなくなった。
どうしよ

Posted by Yappo at 01:00 | Comments (1) | TrackBack

2005年09月07日

Rast 0.3.0が公開されてたみたい

APIの変更点とかが見つけられなかったけど、標準ツールが充実したみたい
http://www.netlab.jp/rast/manual.html.ja

Posted by Yappo at 21:28 | Comments (0) | TrackBack

2005年07月01日

Senna+MySQLをより超高速にするパッチ

当者比50~100倍程のスピードアップ(クエリ/テーブル構造による)のパッチです。

MySQL(特にFullText boolean mode)のlimitの実装はある意味効率の悪い実装になっている。
例えば、limit 100000,100といったクエリを投げると100100行分のデータをディスクから読み込むのである。
まぁ、whereなどの条件に一致する100000件のレコードを先に確定させなければいけない訳で当然といえば当然である。
order byとか使ってたらなおさら。
無論SQL_CALC_FOUND_ROWSなんか使ってると全件確定させなきゃいけないから大変。
当然これらはindexを使用していない時の挙動だと思う。
indexのみが使われたクエリの挙動は未確認だけど。

さて、ここから本題。


では、Senna+MySQLの挙動はどうなっているのか?(in boolean mode)
例え、select * from table where match(field) against('key' in boolean mode) limit 10000,10といったクエリを投げると、必ず10010件の行を読むのである。
limitで絞って高速だぜYeha!なんて思っても思い通りに行かないのである。
いくら、and/orなどの演算子の結合処理などをMySQL側にやらせているからといってあんまり。
各単語のポジションリストだけ見れば、行データを見なくても一致行を確定できるのに。
そりゃ、order byしちゃったり他のフィールドを見たりしたら駄目だけど
見る必要も無いデータを読むなんて無駄杉。

って事で、in boolean mode限定で高速モードを実装しました。
意図した数の行しかディスクアクセスしなくなります。
ヒット件数が多いクエリの

select * from table where match(field) against('+key' in boolean mode) limit 1000, 10;


select sql_calc_found_rows * from table where match(field) against('+key' in boolean mode) limit 10;

等に効果があります。
whereにmatch以外を用いたり、order byしたり、group byしたり、havingした場合の障害には、さらに責任持ちません。

sen_skipmode_setというMySQLネイティブな関数を追加してます。
この関数に値を渡すことによりスキップモードが有効になります。

select sen_skipmode_set(1)

で、スキップモードon
select sen_skipmode_set(0)

で、スキップモードoffです。

使用例は


select sen_skipmode_set(1);
select sql_calc_found_rows title, comment from sites where match(keywords) against('+key +key2' in boolean mode) limit 10000, 100;
select sen_skipmode_set(0);
select found_rows();

って感じでしょうね。


実装方法は、pthread_key_*系のスレッド内のグローバル変数を使って簡潔に仕上げてます。
sen_skipmode_setでの値をグローバル領域に保存しつつ、sql_select.cc内にて、limitの値をグローバル領域に保存して
ft_boolean_search.cでは受け取った値を元にディスクアクセスするかどうかを決定する感じです。

in boolean modeじゃ無い方には対応してません。

現在は、linux上のMySQL4.0.24のみでの動作を確認中むしろ問題なく動いています。
インストールの仕方は、素のMySQLソースにパッチしてください。
mysql-4.0.24.senna.sen_skipmode_set.diff

7/1 17:40追記:
やってしまった。。。
このパッチが

+              share->keyinfo[i].senna = sen_index_create(buf, sizeof(my_off_t), SEN_INDEX_NORMALIZE | SEN_INDEX_NGRAM | SEN_INDEX_SPLIT_ALPHA | SEN_INDEX_SPLIT_DIGIT | SEN_INDEX_SPLIT_SYMBOL, 0, sen_enc_default);

になってた。。。
要するにMeCabを使わずにN-Gramでindexを作るモードです。
iYappoでの導入のために、Sennaのpatchファイルをいじっていたのを忘れてました。。。
いじくってるのはここだけなので、あとは大丈夫です。
問題の行を
+              share->keyinfo[i].senna = sen_index_create(buf, sizeof(my_off_t), SEN_INDEX_NORMALIZE, 0, sen_enc_default);

に書き換えてアップしなおしています。
もし17時40分以前のパッチをお使いの方がいらしたら、再度作り直しをお願いします。

しかもsennaのsvnに反映された後に思い出すなんてタイミング悪すぎる。
ほんとごめんなさい。

Posted by Yappo at 05:02 | Comments (0) | TrackBack

2005年06月30日

Rast0.2.0きたーーー!

ライセンスをGPLからBSD ライクなライセンスへ変更したのが大きな目玉っぽい
新興検索エンジンはどれもGPLに縛られなくなりつつありますな。Hyper Estraierは元から違うけど。
ビッグな追加事項は0.2.1?あたりっぽい

とりあえずRast.pmの更新は待ってくださいorz
マージとかXML-RPCとかそれは心得てますorz

先にSennaのMySQLパッチの有用なパッチつくりを先に。。。


と、ソースコードも追わずに脊髄ポスト

Posted by Yappo at 01:36 | Comments (2) | TrackBack

2005年06月16日

複合語検索ワードの行列演算

パテント対策の走り書き

複合語検索されやすい単語は重要度が高くて
その重要度が高い単語と一緒に検索された単語も重要度が高い

で、それらの関係を表にして行列演算!

なーんか面白いよね?

#ceekの中の人のネタを組み合わせた形で、iYappo上で実物をお披露目しよっと

Posted by Yappo at 22:30 | Comments (0) | TrackBack

2005年06月02日

Rast,Hyper Estraierの性能評価クリップ

Ceekz Logsさんと/.jのOliverさんが、性能評価をしているのでクリップするテスト。

Ceekz Logs Hyper Estraier のお試し結果

前回、調子乗って行っていた100万件のニュース記事のインデキシングですが、9時間ほど掛かりました。これは、月別に差分インデキシングを行ったからかもしれません。合計で 1.0G ほどかな。

他にもソートの速度が気になっているそうです。
Hit件数が多くなるとソートに必要な処理も増えてしまうので、ある程度諦めてしまうのか
高性能な仕組みを考えなくちゃですね。。。
それかインデックスを分割して、後ろの順位をばっさり切り捨てるとか。

Oliver の日記 全文検索エンジン:Hyper Estraier

速度低下はかなりリニアで、とても素直な挙動といえる。indexのサイズも元のデータが693MBなので、かなり優秀。成長させていったindexに対してestcmd optimizeを実行したところ、300MBまで縮んだ。

Oliver の日記 全文検索エンジン:Rast (ちょっとチューン)

ディスク上のDBへのsync回数を減らすことで実時間ベースのパフォーマンスは劇的にアップした。この範囲で5-8倍であるというのは、ストレートにsync回数が減ったのが響いていると思われる。この設定での使用メモリは約300MB。しかし、テストで16万エントリをいっきに登録するテストをしたところ、10万エントリを越えたあたりからパフォーマンスは劇的に低下していった。

初のRastとHyper Estraierを(おそらく)同じ文書群での性能を検証をした情報ではないでしょうか。
Rastでは約4時間40分かかっていたindex処理を、Hyper Estraierでは約12分で完了している模様。
早すぎ、、、ですが詳細なindex条件が記載されていないため参考程度ですな。
自分も検証しないと。。。

BDBをチューニングしたり、RastのDBエンジンをQDBMに変えちゃうとパフォーマンスが上がるのかを試してみたいところ。


ちなみに明日のネタは、YappoLabsの採用基準やiYappoのアーキテクチャを絡めつつ
前回のネタの紹介部分を省いた感じになると予想されます。
シナリオは大体あるので、さくっとパワポが作れるといいな。

Posted by Yappo at 16:39 | Comments (0) | TrackBack

2005年05月30日

Linux Conference 2005でお話してきます

Blog Hakers Conference 2005ではなくてLinuxです。
急遽Linux Conference 2005の全文検索 BOFに出る事となりました。

内容はBlog Hakers Conferenceとは違う方向になるっぽいです。
もうちょっと大局的な内容になるのかな。
後は、実例などがまとめられれば良いのかな・・・
もんたメソッドd(違

せめてHyper Estraierにきちんと触れないと。

Posted by Yappo at 22:19 | Comments (0) | TrackBack

2005年05月18日

Rast.pmをRast0.1.1に対応させた

Rast0.1系が出て結構たちますが、未だにRast.pmが0.1系で動かなかったので動くようにしました。
かぜぶろさんのパッチ適用と新規追加されたフラグに対応しています。
http://tech.yappo.jp/rast/よりダウンロードしてください。
Rastを0.0系から0.1系にバージョンアップをしたらrast-db-convertをお忘れなく。サマリ作成してなくてもDBを開くことが出来なくなります。


近日中に複数DBをまとめて処理できるmergerに対応させたいと思います。
C APIのように、先にDBを開いてからmergerでまとめる処理は行わずに、簡単にDBをまとめられる仕様にしたいところです。

注目のxmlrpc対応ですが、XMLRPC-Cを有効にしても./src/encodings/でmakeがこけちゃってinstallが出来ないから検証してないのと
本家Rastもxmlrpcはオプション扱いなので、Rast.pmに含めるのはやめたほうがいいかなぁと思っていて、優先度低めです。
Rast::XMLRPCな感じで違うパッケージに分けてしまおうかとも思っとります。

どちらにせよ互換性を保ちつつ実装できればなぁと・・・

根が深い問題としては、CPANに登録すべきかとか、名前空間どうすべきかとか、色々あるですが。

Posted by Yappo at 23:35 | Comments (0) | TrackBack

2005年04月12日

SennaがIN BOOLEAN MODE(複合語検索)対応

Senna - ChangeLogより


* applied ftb patch for mysql binding from <ko at yappo.ne.jp>
'IN BOOLEAN MODE' supported

複合語検索モード用のパッチを送った所、手直しをして頂いた後に反映されました。

いまさらですが、過去ここで公開したmysqlパッチも取り込んでいただいており、Sennaのmysql対応は安定してきていると思います。
ひとまずは、使える状態になっていると思うのです。

#mysqlのfulltext関係のいじり所は把握できてきた感じ。

Posted by Yappo at 10:58 | Comments (0) | TrackBack

2005年04月05日

Sennaメモ その弐 (Senna本体patchとmysql4.1系対応)

前回のエントリがぐちゃぐちゃになりそうなので整理。
相変わらず、現時点で最新のrevision6のSennaが対象です。それ以外のrevisionでは役に立たないはずです。

前回のパッチをそのまま適用しても、レコードの削除を行ってからselectを実行するとGot errorが出ます。
挙動としては、削除したのにsen_index_selでヒットする文書数が減少しない物でした。

原因がわかり、パッチを作成しました。
senna(rev6用)パッチ(修正版 ver.2)を当てて、Sennaを再構築してみてください。
また、mysqlもmake installしなおす必要があります。

原因ですが、SennaのAPIにindex作成をするsen_index_addと、index削除を行うsen_index_delという関数があるのですが
それぞれ、index対象の文章を引数に指定する必要があるのです。
そして、引数に設定された文章を単語に分けてからindexの登録/削除を行っているのです(おおざっぱな説明)
で、Sennaはn-gramとmecabを利用して単語に分割処理をしますが、revision6の上記APIはなんと
sen_index_addではmecabを使って単語の分割を行い、sen_index_delではn-gramで単語の分割を行う。
という事です。

追記:パッチに不具合がありました。
addとdelで、n-gram解析をして取得する文節数に違いが有り(del時の解析がおかしかった)Got errorが出てしまっていました。
delのn-gram手法をaddに合わせたので、今度こそ平気なはず。
(だんだん、とりあえず動くパッチになってきてるな・・・)

追記2:検索結果がおかしいと思ったら、検索クエリの文字列分割処理がmecabのままだった。
クエリの字句解析もn-gramにしました。

次回以降のVerUPで修正されるだろうと思い、場当たり的にn-gramのみ対応するようにパッチを書きました。
このパッチを当てたら、多分mecabは使用されません。
多分SEN_INDEX_NGRAMを実装する手前なんだろうなぁ。


あと、某deliciousより

mysql 4.1も欲しい。

との事なので、mysql4.1.10aに対応させるパッチも作っておきました。(さらに軽い検証のみ)
パッチ後にaclocal,autoconf,automakeで普通にインストールできます。

  • mysql 4.1.10a用Sennaパッチ
  • mysql 4.0.24用Sennaパッチ
  • mysql 4.0.23用Sennaパッチ
    追記:パッチに修正を加えました。fulltextインデックスが張られているテーブルが含まれたdbをdrop databaseするとcan't rmdirが出てdrop出来ない不具合の修正です。

    Posted by Yappo at 03:44 | Comments (0) | TrackBack
  • 2005年04月04日

    Sennaメモ その壱 (with patch)

    Senna
    先月末より公開された、未来検索ブラジルの成果物。
    N-gram&MeCabな全文検索システムです。

    たとえば・・・
    組み込み型全文検索エンジン Senna : NDO::Weblog

    実は、はてなブックマークのブックマーク検索はこの Senna + MySQL で実現されています。

    と、導入実績がちゃんとあったりします。
    他にも、あんなのやこんなのにも導入されているそうです。

    #このメモはsvn Revision 6を対象としています。
    #テスト環境はRHL9です。

    いけてそうなSennaですが、公開したてということも有りインストールが大変です。
    svnでとってきたソースツリーはaclocalとかautoconf,automakeすればインストール出来るのですが
    mysqlの全文検索機能に対応させるには一筋縄ではいきません。
    むしろ、コンパイルできません。
    無理です。

    何故かと言うと…
    Sennaについてきているmysqlのpatchファイルなのですが、Revision6のAPI仕様に則していなくて
    付属のpatchを当てたところで、コンパイルできないのです。


    って事で、Senna Revision 6に対応したmysqlのパッチを作りました。

    注:レコードをdeleteすると、クエリによっては

    ERROR 1030 Got error 134 from table handler

    となってしまいます・・・
    なので、一時パッチ公開停止orz(なんだかSennaがレコードのdeleteが出来てないような気がする。。。)評価用に使ってください。Senna自体にもパッチ当てればok


    mysql 4.0.23用Sennaパッチ(レコードのdeleteを実行するとselectが出来なくなります)
    このパッチを当てた後は、aclocal,autoconf,automakeした後、通常のインストール作業を行ってください。

    mysqlのインストールの前に、mecabとsennaをインストールしておいてください。
    mecabは--enable-mutexオプションをつけてconfigureしておいてください。

    これで、mysqlの全文検索機能のエンジンにSennaが利用されるようになります。


    mysql 4.0.24の場合…
    mysql 4.0.24用Sennaパッチ(レコードのdeleteを実行するとselectが出来なくなります)
    4.0.23とほぼ同じですが、makeする前に4つほどファイルを作成する必要があります。


    touch ./Docs/Images/cluster-components-1.txt
    touch ./Docs/Images/multi-comp-1.txt
    touch ./Docs/errmsg-table.texi
    touch ./Docs/cl-errmsg-table.texi

    パッチ当てた影響で、ドキュメントの再作成処理が入るのですが、なぜかこれらのファイルが足りないようです。
    原因については本来の目的とは違う物なので、特に調べてもないです。
    4.0.24での注意点は以上です。


    実際に動くかどうかも試してみました。


    Welcome to the MySQL monitor. Commands end with ; or \g.
    Your MySQL connection id is 3 to server version: 4.0.24-log

    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

    mysql> create table test (a text, fulltext(a));
    Query OK, 0 rows affected (0.02 sec)

    mysql> insert into test set a='うほあぐぇryhぱrはあゑrftgyふじこlp';
    Query OK, 1 row affected (0.21 sec)

    mysql> select * from test where match(a) against('ふじこ');
    +-------------------------------------+
    | a |
    +-------------------------------------+
    | うほあぐぇryhぱrはあゑrftgyふじこlp |
    +-------------------------------------+
    1 row in set (0.00 sec)

    mysql> select * from test where match(a) against('じこ');
    +-------------------------------------+
    | a |
    +-------------------------------------+
    | うほあぐぇryhぱrはあゑrftgyふじこlp |
    +-------------------------------------+
    1 row in set (0.01 sec)


    いい感じね。

    ちなみに、現運用系のiYappoのDBをコピーしてきてFULLTEXTインデックスつけてみましたが、ちゃんと動きました。
    検索速度もいい感じです。


    一応、パッチの補足などを…

  • sen_index_result_*系の関数名をsen_records_*系に変更
  • sen_index_openの引数合わせ
  • myisam/mi_open.cでsennaのindexを開く処理のところにsen_index_createを追加
    つーかindex作成処理がどこにも入ってなかった。(本来ならmyisam/mi_create.cに書くんだろうけど、ごみごみしてるからやめた)


    追記:
    MySQLとSennaの組み合わせがmakeできた。

    このへんに「全文検索専用のデーモンを立ち上げなきゃいけない」とかあったけど、そんなことはなさそう。

    全文検索を行わせる専用のmysqldを立ち上げなきゃいけない、という意味だったです。
    Sennaが、専用デーモンが必要というのではなくて、iYappoで使うとしたら専用のmysqldが必要だなぁ・・と。

    Posted by Yappo at 22:11 | Comments (0) | TrackBack
  • Senna開発ページ

    Senna開発ページ

    ここは未来検索ブラジル社の全文検索エンジンSennaに関する情報を置く場所です。

    なんだか発見しました。
    Sennnaの開発ポリシーの片鱗がちらちらって感じです。

    iYappoではRast採用が濃厚ですが、別ネタではSennaも使ってみようって事になったので色々やってみる年頃。

    Posted by Yappo at 14:49 | Comments (0) | TrackBack

    2005年03月30日

    Rastメモ その壱

    Rast
    先月末より公開された、未踏プロジェクトの成果物。
    N-gramな全文検索システムです。

    特徴としては

  • use BerkeleyDB & APR
  • Rast API
  • N-gram
  • 文書の属性値を自由に設定可能
  • ソート対象を独自の属性値に指定可能
  • Rubyバインド
  • 指定したすべての属性値に対しての検索
  • 分散化(対応予定)

    ライブラリ化してあるため、APIを用いて自分好みの検索プログラムを作成できます。
    現在は簡単なサンプル検索システムのコードが付属。
    現在はVer0.0.1で、8月に正式リリース予定。
    BerkeleyDBとAPRを用いているため、現時点でも安定している感じ。

    特にN-gramや、文書属性を自由に設定できてソート対象に出来るなんて所がツボにきました。
    C言語に抵抗がなくてAPRに慣れている人には、良いライブラリかも。

    今のところ、ユニークな属性を設定してしまうと文書を削除しても内部的に削除されないようで、同じ属性値のデータをupdateする事が出来なくなります。
    具体的には、削除フラグをセットしてるだけでdeleteしてないっぽ。

    他にもindex作成中はDBにロックがかかって検索出来なくなるので、いったんDBをコピーしてからindexの更新をしなきゃいけなさそう。
    mknmzなんかは、この辺りを自動的にやってくれてるけど、rastだと自分で処理してあげないとな。
    yappodなんかも、rastとにいかよった部分があってコピーしてindex更新してたっけ…

    indexサイズは、属性の取り方で変化しますが、約6万件600MBのデータが約400MBくらいになってます。
    大部分(300MB)が単語出現位置用ファイルにて消費されとります。
    indexのスピードは、感覚的にそこそこって感じでしょうか。スケールしだいで遅くなるのかなぁ。

    バインディングは、標準でRubyのライブラリが添付されていてPHPも公開されていたのですがGPL/LGPLとかのライセンス問題で公開停止中…
    Perlはまだないっぽい。

    追記:Sennaってのもあるみたい。2ch検索の中の人かなぁ

    Posted by Yappo at 13:03 | Comments (3) | TrackBack
  • 2004年11月18日

    5~8年前の妄想

    ふと思い出したのでメモ


    DNS的な検索システム

  • 各Webサーバが、上位のクロウラーサーバに対して自サーバで管理してるドキュメント情報を送信する
  • 各サーバは、自サーバのコンテンツをインデックス
  • 親サーバにはさらに親サーバが居る
  • スターにはならないけどツリー+α的なネットワーク構造
  • キャッシュやクラスタリング用等の特殊なノードも居る
  • 検索クエリーは、全ノードから発生する
  • 検索クエリーとレスポンスの伝播は状況に応じて変化
  • 基本的に転送内容などはキャッシュ
  • クエリーを投げてから一定時間(レスポンスタイム重視)でタイムアウト
  • タイムアウト以降に発生し続けるレスポンスパケットは、どっかで止めてキャッシュ
  • 実はWebサーバはしたたかに、自分が保持するコンテンツを周りに広報する

    問題点

  • ネットワークに流れるデータ量
  • 今で言うgoogle八分対応
  • installのしやすさ
  • インデックス作成速度

    とかとか


    今になって振り返れば、グリッドとかP2Pとかそんな感じなのかな。
    どうりでPerl版Zigumo(P2Pソフト)エンジンの開発に魂削ったわけだ。

    当時はGopherとかDNSとかの考え方に影響されて妄想してたんだけどね。
    なんというか、商売にしにくいモデルだな。

    でも誰かこれ実装してみません?
    叩けば沢山構想が出るはず。


    これ書いてたらZ80ポケコンにSystem7っぽい嘘マルチタスクOS作って、ポケコン本来の機能に割り込み入れたバージョン作っちゃって
    nekoプログラムが数プロセス動いてる4行のポケコン画面でBASIC作ったりとか。
    人のポケコンと自分のポケコンをクリップでつなげて、何かをネットワークインストールしちゃったりとか。
    ろくでもない事まで思い出してしまった(遠い目)

    とか書いてたら、ひらがな+よく使う漢字のビットマップフォント作ってROMに入ってるシリアル通信ルーチンよりもチューニング(NOPとかクロックとステートメントの実行サイクルから計算したダミーステートメントの角度とか)
    したルーチン作って、ポケコンとモデムを無理やりつないでE500シリーズじゃない方のシャープのポケコンで東京BBSにつないでたの思い出した。
    角度とか光度とか輝度とか全部ガチアセンブラで何やってたんだろ。。。
    ポケコンシンセサイザも作ってたな。。。ORZ
    しかも嘘っぱちPCM対応。

    Posted by Yappo at 04:15 | Comments (1) | TrackBack
  • 2004年08月05日

    Namazu検索時の分かち書き方法を変更するパッチもどき

    本題に入る前にblogdbで楽天を検索してみたらなんだか凄い事になってるようで…
    http://blogdb.jp/search?key=%E6%A5%BD%E5%A4%A9&day=2004-8-5

    やっぱblog検索はwebとは違う意義があるなと再認識したり。


    Namazuの検索コマンドなんですが、検索時の分かち書きだけはNamazu独自の仕組みを使ってるみたいなんですよね。
    blogdbで引っかからない単語とか、分かち書きの結果がおかしいクエリがあるなとおもってソース見たら
    wakati.cなるソースコードの通りになってたわけで…
    要するにmknmzでの分かち書きとは違う分かち書きされるわけで
    そういうことなんです。
    Chasenでインデックスつけてたからどうしようかと迷いそうになった。

    って事でsearch.cをちょっくら改造

    NmzResult
    nmz_do_searching(const char *key, NmzResult src)
    {
    ~略~
    nmz_debug_printf("after nmz_strlower: [%s]", tmpkey);

    {/* Yappo Path Start */
    char *p = tmpkey + strlen(tmpkey) - 1;
    for (; p >= tmpkey; p--) {
    if (*p == '^') {
    *p = '\t';
    }
    }
    }/* Yappo Path End */


    mode = detect_search_mode(tmpkey);
    if (mode == ERROR_MODE) {
    val.stat = ERR_FATAL;
    return val;
    }

    if (mode == WORD_MODE || mode == PHRASE_MODE) {
    remove_quotes(tmpkey);
    /* If under Japanese mode, do wakatigaki (word segmentation) */
    if (0) { /* Yappo Path */
    if (nmz_is_lang_ja()) {
    if (nmz_wakati(tmpkey)) {
    val.stat = ERR_FATAL;
    return val;
    }
    /* Re-examine because tmpkey is wakatied. */
    mode = detect_search_mode(tmpkey);
    }
    } /* Yappo Path */
    }

    delete_beginning_backslash(tmpkey);

    って事をしておく。
    んでもってnamazuコマンドに投げる前にキーワードをchasenで分かち書きしておく
    んで、分割された単語を^でくっつけておく。

    そうすると、Namazuの分かち書きに頼らずに独自の分かち書きを適用させてからフレーズ検索を実行できると。
    まぁ、Namazu独自の分かち書きが実行されなくなるけど、その方が都合よいときあるし。


    libchasenとまとめたり色々するのも手だけど、めんどっちい事は後々もめんどっちい事になるからね。


    おかげで検索時の再現性が上がりました。


    2001年当時のNamazuのソースと大分変わっていてびっくりした。

    Posted by Yappo at 03:38 | Comments (5) | TrackBack

    2004年07月06日

    yappod 1.1.0系

    ちょっと色々あるのでyappod 1.1.0系の整備を急いでやることになりそう。
    1.0.0との差は、キーワードポジションリストの仕様変更やバークレイDBの仕様をやめたり
    FreeBSDでも無理やりコンパイルできたりって感じ

    Posted by Yappo at 20:21 | Comments (0) | TrackBack

    2004年07月01日

    方針転換と分散ファイルサーバ

    とりあえず書き置きを掲載し忘れてたのでのっけとく。
    具体的な物は後ほど

    色々とネタは浮かんでいたのだけど、全部を一つのデーモンにまとめるのは
    さまざまなコストがかかりすぎるのでやめることにした。
    大まかな方針を変更してしまい、シンプルに構築していこうかと思う。

    って事で、まずはwebロボットについて考えた。

  • 複数サーバで分散して集める
  • 各ノードごとに担当するドメインを割り当てる
  • URLの更新頻度により再訪問間隔を自動調整
  • その他いろいろ

    複数のサーバに収集したファイルが格納されるので、インデクサに効率よくファイルを転送する手段が必要になる。
    他にも色々な要因があるので、分散ファイルシステムを簡易に構築して収集したファイルを管理する事にする。
    大まかにはGoogleで利用されているGFSのような仕組みを作ろうと思う。
    インデックスファイルをここに格納するかは後で考える。
    適当な仕様は↓な感じで
    1.指定する文書がどのノードに保存されているかを把握するメタサーバが必要
    2.メタサーバのDBはMySQLで
    3.メタサーバのテーブル構成は下記の感じ
    ドキュメント番号管理テーブル
     ファイルパスとそれに対応するユニークな数値を記録
     検索エンジンの文書IDにも使いまわす
    ファイル配置管理テーブル
     どの文書IDがどのノードに格納されてるかを管理する
     文書は分割されて複数のノードに保管されているかもしれないし
     同じデータが複数のノードにミラーリングされてるかもしれない
     大体下記の内容を管理
     文書ID,ノードID,文書サイズ,ファイルのどの場所が保存されているか,保存されている内容のハッシュ,最終更新日時
    ノード管理テーブル
     ノードID,ノードのip addr,ノードの死活管理データ
     などなどを管理
    4.クライアントは読み書きしたいファイルの文書IDをメタサーバのMySQLに直接つないで文書IDを取り出す
    5.新規文書だったらノードを適当にクライアントが選択する
    6.クライアントがノードに直接接続して、データを含めてジョブをノードに投げる
    7.書き込み処理系だったら、ノード内部にデータを書き込んで、ノードからメタサーバに変更内容を書き込む
    8.読み込み処理ならノードがクライアントにデータを返す

    大まかにこんな感じ
    実際はファイル更新や追記書き込みやノード間のデータミラーリングとかガベージコレクションとか色々考える事は有る。
    ノード側のデータ管理も、ノード毎に立ち上げられたMySQLを利用すると思う。
    データに関しては、普通のファイルとして保存する。
    多分複数の文書を1個のファイルにまとめるだろうけど。
    あとこのファイルシステムを簡単に取り扱うAPIも必要だね。

    メタサーバはMySQLに任せてノード間同士の協調処理はノードにやらせ、クライアントはジョブを投げるだけになるのかな。

    Posted by Yappo at 16:00 | Comments (0) | TrackBack
  • 2004年04月06日

    これから作る検索エンジンについて

    しばらく携帯サイトばっかりやってサボっていたせいですっかり世の中が変わっているらしい。
    blog、SNS、XML、SOAPにRSSと実用的になったものや新しい言葉が出てきたようだ。

    で、新規の技術が出たわけではなく、ただ単に言葉が新しいわけであって技術的な要素は新しいわけでもない。
    そんな事は誰でも分かってるわけで今更突っ込みいれた所でどうとでもないけどね。
    フォーマットが統一されつつあるという点では便利になった。

    現在これらの流行の要素やこれからの事を一生懸命見回ってリハビリをしているわけで。
    これから作る検索エンジンシステムに必要な要件の洗い出しを始めている。

    一番重要な事は
    RSS(atomとかひっくるめて)フィードを持つサイトを特別扱いをする
    の一点に尽きる。

    米Yahooでやっているような物ではなく、システムがサイト構造を理解をする手段として利用する。
    色々調べまわったが、検索ロボット君が理解できるサイト構造をまとめたフォーマットは存在していないらしく。
    結局はRSSを使うしかないようである。

    何が出来るかというと、RSSは記事のヘッドラインを取り扱う特性からサイト内でのメインコンテンツが収められている
    URIと言うものを補足しやすくなるわけである。
    RSSに対応したサイトでRSSに乗らないURIは、説明ページであったり補足コンテンツになる事が多いため
    RSSに登録されているURIの重要度を引き上げると有益な情報を提供しやすいと考えられる。

    他のネタとしては、ページ中に記載されている住所や郵便番号を抽出し、街区レベル位置情報
    http://nlftp.mlit.go.jp/isj/
    を利用して、URIやサイト単位で物理的な位置情報をマッピングしてあげて関連度検索に役立てる
    という事も、その面白さは計り知れない。

    お役所で提供されているデータは結構あるので、それらを効率よく使うと面白い事が沢山出来そうである。


    で、肝心のシステム開発は。。。
    独自(Apache参考にした)メモリプール機構をどうするか固まったです。
    APRを何故使わないかというと、コストがかかりすぎるから。
    現在公開中のyappod-1でも、クラスタリングに対応しているけど
    それとは比べ物にならないくらい程しっかりとした物にしないといけないな。

    概要は

  • モジュールを動的に組み込み、取り外せる
  • クラスタリングの構成を動的に制御
  • ストレージ分散
  • 各モジュール、クラスタ間はメッセージ機構により協調動作する
  • 管理用Webサーバ内蔵
  • mod_phpの移植
  • 上の方で長ったらしく書いてる事は飾りでしかないのです。それが偉い人にはわからんのですよ。


    適当に書いてるから読みにくいね。

    Posted by Yappo at 11:17 | Comments (0) | TrackBack