関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
autocommitの設定値でインデクシング時間に大きな差
contrib/benchmarkを使って2.4と2.9のインデックス作成時間を比較していたMark Miller氏は、2.9で大幅な速度向上を発見。2.9は3分少々の処理時間のところ、2.4は20分以上もかかっている。原因を追及していくと、Lucene 2.4と2.9のautocommitのデフォルト設定値の違いであることが判明した。

2.9はautocommit=falseがデフォルトであり、2.4はtrueである。2.4でもfalseにすると、2.9と近いプロファイルを示し、処理時間も4分程度に縮まった:

http://www.nabble.com/benchmark%3A-lucene24-vs-lucene29-td24835195.html
| 関口宏司 | Luceneパフォーマンス | 08:38 | comments(0) | trackbacks(0) |
よりソートが速くなったLucene 2.9
Lucene 2.9はソートがより速くなった。まず先日の記事で紹介したとおり、スコアが不要の時はScorerを呼ばないようにすることができるようになった。

また複数セグメントのインデックスにおいて、IndexReaderのreopen()時に変更のないセグメントは再読み込みしないようにしてwarm-up時間を短縮できるようになっている:

https://issues.apache.org/jira/browse/LUCENE-1483

つまり、ソート時に使用するFieldCacheの内容が引き継がれるのでIndexReaderのreopen()後のソートがこれまでより速くなることが期待できる。
| 関口宏司 | Luceneパフォーマンス | 09:54 | comments(0) | trackbacks(0) |
NIOFSDirectoryでパフォーマンスアップ!(Linux)
Lucene 2.4から導入されたNIOFSDirectoryはぜひLinuxプラットフォームでは積極的に使うことを考慮すべきである。一般的にパフォーマンスが良くなる。

ただWindowsでは逆に遅くなってしまい、現在のところWindowsではFSDirectoryを使った方が良い。これはSunのJavaのバグが原因とのことらしい:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6265734

| 関口宏司 | Luceneパフォーマンス | 00:30 | comments(0) | trackbacks(0) |
(メモ) 性能など・・・
http://wiki.statsbiblioteket.dk/summa/Hardware

http://wiki.statsbiblioteket.dk/summa/IndexBuilding
| 関口宏司 | Luceneパフォーマンス | 10:23 | comments(0) | trackbacks(0) |
Solrでの検索タイムアウトのサポートとその効用
Lucene 2.4では検索のタイムアウトがサポートされるが、Solr 1.3でもサポートされることとなった。

検索エンジン・サーバ側に検索処理時間のタイムアウトを設けるのは、検索クライアント側でタイムアウトを設定するのと比較し、次のようなメリットがあると考えられる:


  • クライアント側でタイムアウトを設定すると、検索がタイムアウトになったときは検索結果が一切得られないが、サーバ側でタイムアウトが設定できれば、タイムアウトに達するまでの時間に収集した一部の検索結果が得られる。これは特に分散インデックスを複数のshardを使って横断検索する場合に重要になる。

  • クライアント側でタイムアウトを設定してしまうと、サーバ側の検索処理が無駄になってしまう。サーバ側では使用されることのない検索結果を収集するためにサーバリソースを消費してしまう。検索サーバ側にタイムアウトを設定できれば、このような無駄なリソース消費はなくなる。


| 関口宏司 | Luceneパフォーマンス | 12:28 | comments(0) | trackbacks(0) |
ホワイトペーパー「LudiaとSolrにおけるファセットカウント取得と絞り込み検索」の公開
ホワイトペーパー「LudiaとSolrにおけるファセットカウント取得と絞り込み検索」を公開した。

http://www.rondhuit.com/download.html
| 関口宏司 | Luceneパフォーマンス | 10:49 | comments(2) | trackbacks(0) |
IndexReader.reopen()
IndexReaderクラスのreopne()メソッドは、もうじきリリースされるとうわさされているLucene 2.3の新機能である。これまでインデックスをオープンするのにIndexReader.open()メソッドしかなかったが、reopen()が加わった。アプリケーションでreopen()を使うことで、open()メソッドよりも性能改善が見込める。

使い方は、reopen()はインスタンスメソッドなので(open()はクラスメソッドである)、既存のIndexReaderオブジェクトに対してreopen()を呼び出し、新しいIndexReaderオブジェクトを得る。古いIndexReaderオブジェクトはその後close()をする。

インデックスが更新されたら、検索結果に更新分を反映させるためにこれまではIndexReader.open()を呼んで新しいIndexReaderオブジェクトを取得する必要があった。

Lucene 2.3では新しいIndexReaderを取得するのにreopen()が使える、ということである。reopen()はインデックスの更新差分のみロードするので性能が改善するのである。

どのくらい改善するのか測定してみたところ、次のようになった。

プログラムはランダムな単語が100万単語ずつ増えていくインデックスから任意の1単語を100万単語増えるごとに1回、計5回検索したときの合計タイムを計測するものである(したがってプログラム終了時はインデックス内には500万単語が存在する)。

open [ms]reopen [ms]
1回目165125
2回目190126


2回ずつ計測してみたが、24%から34%程度reopen()の方が速くなっていることがわかる。
| 関口宏司 | Luceneパフォーマンス | 07:55 | comments(0) | trackbacks(0) |
ホワイトペーパー「Solrの検索性能」
6万円のノートPCで毎秒200クエリを達成
「Solrの検索性能」 - ホワイトペーパー無料ダウンロード
| 関口宏司 | Luceneパフォーマンス | 08:25 | comments(0) | trackbacks(1) |
Luceneインデックスのバージョンの活用
LuceneのインデックスがWebアプリケーションサーバのプログラムから検索できるようになっている環境を考える。そして、クライアント(Webブラウザ)からの検索リクエストはHTTP GETメソッドで投入されるとする。このとき、リクエストパラメータ"q"に検索式が設定されることとする。たとえば、こんな具合である:



GET /search?q=lucene



すると、Luceneの検索サービスを提供しているWebアプリ側はqパラメータから検索式を取り出して検索し、検索結果をHTMLなどに整形してクライアントに返す。

次にその同じクライアントは、しばらくしてまたこんな検索リクエストを投げてよこすかもしれない:



GET /search?q=lucene



これは上とまったく同じリクエストなので、Luceneのインデックスが同じである限り(そして、ランダムに広告などを切り替え表示するのでもない限り)、先の結果と同じHTMLを出力して返すこととなる。

これはまったく無駄な処理だ。

このようなときに、クライアント側にキャッシュ機構があればそれを活用できるというHTTPの仕様がある。そこで、これをどのように実現するか考えてみよう。

クライアントのキャッシュを活用するには、検索結果をサーバから返すときに、Last-Modifiedというレスポンスヘッダをつけてクライアントに渡すようにする。Last-Modifiedにはインデックスの最終更新日を設定すればいいだろう。

すると、キャッシュ機構を持つクライアントは、同じ検索リクエストを発行するときにIf-Modified-Sinceというリクエストヘッダをつけて送ってくる。If-Modified-Sinceに設定されているのはLast-Modifiedで受け取ったインデックスの最終更新日である。

そこでサーバは、その日付とインデックスの更新日を比較し、インデックスの更新日が新しくなければ検索やHTML生成をせずに直ちに304(Not Modified)を返せばよい。304を受け取ったクライアントは、キャッシュ内のコンテンツを再利用するので、応答速度があがる。

具体的な実装方法はというと、サーブレットでgetLastModified()をインデックスの最終更新日を返すようにオーバライドするだけである。するとコンテナは、Last-Modifiedにこのコンテナの値を設定して返してくれる。さらにクライアントからIf-Modified-Sinceが送られてきたときにgetLastModified()を呼び出して日付を比較し、doGet()を呼んでHTMLを生成して返すか、doGet()を呼ばずに304(Not Modified)を返すかを自動的に判断する。

Luceneのインデックスの最終更新日の取得には、java.io.Fileクラスなどを使う必要はなく、インデックスに振られているバージョンを使うことができる。Luceneのバージョンのlong値はそのままDateに変換できる値であり、インデックスが作られた日時を表しているからである(Lucene本 P.108)。

JavaサーブレットとHTTPの仕様、およびインデックスのバージョンをうまく組み合わせることで、検索応答性能を大幅に上げることができる。サーバのCPUの節約にもなるので、負荷がそれなりにある状況下ではスループット(=QPS)の向上にも役立つだろう。
| 関口宏司 | Luceneパフォーマンス | 11:14 | comments(0) | trackbacks(1) |
現trunkでより速くなったLuceneのインデクシング処理
Luceneのインデックス作成処理性能は進歩を続けている。現在のtrunkのパフォーマンスはかなりあがっている。

グラフは10のユニークワードからなる1つのフィールドを持つドキュメントを1万件登録したときの処理時間をプロットしたものである。Lucene 2.0、2.1、2.2およびtrunkで計測した。

インデックス作成時間比較

バージョンがあがるほどだいたい速くなっているが、特に現trunkでの処理時間の短縮が際立っている。

なお、trunkバージョンからFieldクラスにsetValue()というメソッドが追加された。このメソッドを使うと、Fieldインスタンスをnewせずに使いまわすことができる。そのため、GCの発生を抑制し、結果的にパフォーマンスの向上に貢献するようである。

今回の簡単なテストではその効果があまり見られなかったのでグラフには掲載していないが、プログラムによっては効果があるかもしれない。
| 関口宏司 | Luceneパフォーマンス | 02:18 | comments(0) | trackbacks(0) |
+ Solrによるブログ内検索
+ PROFILE
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< May 2018 >>
+ LINKS
検索エンジン製品 - 比較のポイント
商用検索エンジンを購入した企業担当者は読まないでください。ショックを受けますから・・・
>>製品比較 10のポイント
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
Apache Solr入門 ―オープンソース全文検索エンジン
Apache Solr入門 ―オープンソース全文検索エンジン (JUGEMレビュー »)
関口 宏司,三部 靖夫,武田 光平,中野 猛,大谷 純
+ RECOMMEND
Lucene in Action
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless
FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
qrcode
+ SPONSORED LINKS