トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

BugTrack-wiki/302

ページの作成や編集にはユーザ登録が必要です。

検索を行うとサーバに高負荷をかけてしまう

  • 投稿者: 名無しさん
  • カテゴリ: プラグイン
  • 優先度: 緊急
  • 状態: 提案

 内容

ページ内容も対象にした検索を行うとサーバに高負荷をかける事が容易になる。

 条件

  • 想定外の大きさのページがWikiに存在する
  • サーバのスペックが充分でない
  • CGIの動作時間を制御していない(制御できない)
  • 標準プラグインなど Jcode->new($page)->tr('a-z','A-Z') を使っている検索が使用可能である

 具体例

AMD系CPU 1.5GHz 程度の速度で ファイルサイズが2MB(パース前) の物が存在するWikiを検索した場合、5分以上高負荷を継続できるようです。

Wiki側で対策する必要があるか?と言う意見も出そうですが、念のため投稿しておきます。


追記です

複数回計測の平均ではないので正確さに欠けますが、どれほどの差になるのかBugTrack-plugin/21を使い計測してみました。 (Windows2000 + AN HTTPD + ActivePerl 5.8.8 + FreeStyle Wiki 3.6.2)

処理時間(sec) 処理効率 検索対象個数 最大ファイルサイズ
32.515 10.0 files/sec 328 1601969
3468.437 0.09 files/sec 328 1601969
836.703 0.39 files/sec 328 797663
209.968 1.56 files/sec 328 400357
51.093 6.42 files/sec 328 194563
12.421 26.4 files/sec 328 145649
5.031 65.2 files/sec 328 96735
3.118 104 files/sec 327 56100

極端に大きいファイルがたった1ファイルでも存在すると、それだけで大きな速度低下を引き起こす場合があるようです。 標準で利用できるSearchプラグインやBugTrack-plugin/235等を利用している場合、内部の

Jcode->new($page)->tr('a-z','A-Z')

といった、ページを丸ごと投げてしまう部分がボトルネックになり上の表のような処理効率になります。

太字はページサイズが一定を越える場合、行単位に分割してから順に

Jcode->new($line)->tr('a-z','A-Z')

を利用するように修正を加えた場合の計測値です。 本当ならバイト単位で分割する形が最適だと思います。

Wikiを利用されているOSやサーバ等システム次第で負荷の割合が変わるかもしれません。 また、この状況に遭遇する事もおそらく稀ですが、いたづらされかねない環境で利用されてる方は一応対処(Searchプラグインを無効にするだけでも)しておいた方がいいと思います。

 非公式パッチ

取り急ぎ対処されたい方向けのパッチです。 必要無い場合は当てる必要はありません(余計な処理が入るので検索速度が下がります)。 半端にしか対策できていないので、適切なパッチが公開されるまで臨時でお使い下さい。

このパッチは、ボトルネックになりうる大きなページが、適切な改行の入った通常のページである場合のみ有効です。 ページが1行で大きなサイズである場合(行単位で分割が出来ない)等は効果がありませんので、完全に対処する場合はページ保存時に1行のサイズを制限する もしくは 分割を行単位ではなくバイト単位で行うパッチの作成等の対策が必要になります。 バイト単位で分割処理するパッチは、2バイト文字の処理をわかってないのでできませんでした。

標準のSearchプラグイン用パッチ (3.6.2)

SearchHandler.pm (3.6.2)

           my $page2 = ($word =~ /[A-Za-z]/) ? Jcode->new($page)->tr('a-z','A-Z') : undef;

上記の行を次のように変更

           my $page2 = "";
           if($word =~ /[A-Za-z]/){
             if ((length $page) < 131072) {
               $page2 = Jcode->new($page)->tr('a-z','A-Z');
             } else {
               my @page2_buf;
               foreach (split(/\n/, $page)) {
                 push (@page2_buf, Jcode->new($_)->tr('a-z','A-Z'));
               }
               $page2 = join("\n", @page2_buf);
             }
           } else {
             undef $page2;
           }

BugTrack-plugin/235用パッチ

Install.pm

           $page2 = Jcode->new($page)->tr('a-z','A-Z');

上記の行を次のように変更

         if ((length $page) < 131072) {
           $page2 = Jcode->new($page)->tr('a-z','A-Z');
         } else {
           my @page2_buf;
           foreach (split(/\n/, $page)) {
             push (@page2_buf, Jcode->new($_)->tr('a-z','A-Z'));
           }
           $page2 = join("\n", @page2_buf);
         }

 コメント

  • ここまで書いておいてなんですが、バグトラックとしての投稿が不適切であればご指摘ください。 - 名無しさん (2007年04月11日 20時44分37秒)
  • 根本的にはインデックスを作っておいて検索するといった対処が必要ですね。前から問題だとは思っていたので、なんとかしたいところです。 - たけぞう (2007年06月14日 12時50分34秒)
  • この辺りも何とか改善したいですね。最近とてもここ(公式サイト)の速度の遅さが気になります。以前からたけぞうさんがおっしゃっていた、『遅い』という部分が実感として感じるようになってきました。 - あき (2007年07月12日 12時19分58秒)
お名前: コメント:

最終更新時間:2014年02月03日 18時56分40秒