2017.12.15 Friday
スポンサーサイト
一定期間更新がないため広告を表示しています
| スポンサードリンク | - | | - | - |
関口宏司のLuceneブログOSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
2009.10.27 Tuesday
インデックスのサイズを見るシミュレーションプログラム
Luceneのインデックスは検索しながら更新していると、古いインデックスを参照しているSearcherがいる間はセグメントを消すことができない。そのため、大きなマージが走るときはハードディスクの容量を一時的に大量に消費する。
その様子(マージの部分のみ)をシミュレーションする(Luceneを一切使用しない)プログラムを作成した。プログラムを実行するとCSVファイルが出力される。それをEXCELで表示したのが下の図である: EXCELで表示できるよう、この図ではマージ係数を3に設定している。プログラムは以下の通りである: public class MergeSimulator { static final String CSV_FILE = "segments.csv"; static final int MERGE_FACTOR = 3; static final int MAX_BUFFERED_DOCS = 3; static final int NUM_DOCS = 3000; public static void main( String[] args ) throws FileNotFoundException { Directory dir = new Directory( MERGE_FACTOR ); PrintStream ps = new PrintStream( CSV_FILE ); dir.logHeader( ps ); Writer writer = new Writer( MAX_BUFFERED_DOCS, dir, ps ); for( int i = 0; i < NUM_DOCS; i++ ){ writer.add( new Doc() ); } ps.close(); } static class Doc { } static class Segment { private final int level; private final int numDocs; private boolean deleted; public void delete(){ deleted = true; } public boolean isDeleted(){ return deleted; } public Segment( int numDocs ){ this( 0, numDocs ); } public Segment( int level, int numDocs ){ this.level = level; this.numDocs = numDocs; } public int getSize(){ return numDocs; } public int getLevel(){ return level; } } static class Directory { private final int mergeFactor; private List 2009.10.25 Sunday
setRAMBufferSizeMBの上限を明確化(2.9.1)
Lucene/Solrでヒープの消費に影響するパラメータのひとつであるIndexWriterのsetRAMBufferSizeMB()メソッドに渡す引数に、明確な上限値が設けられた:
https://issues.apache.org/jira/browse/LUCENE-1995 (今回のLUCENE-1995の問題は違うけれども)OutOfMemoryError(OOM)はLucene/Solrコミュニティでも常に話題の上位にランクインしている。繰り返し質問されるのは結局のところ、原理がよく理解できていないのが原因と思われる。インデックスサイズが増えたときにOOMに遭遇し、物理メモリを増やし-Xmxパラメータを増やすことでしのいでいる方は、ぜひ体系的にSolrを学び直すことをお勧めします。;-) アフターサポート付き「速習 Solr 1.4」受講者募集中! 内容的にあまりに詰め込みすぎたため、年内に閉講するかもしれません。 2009.10.14 Wednesday
BooleanQueryの不具合修正(2.9.1)
BooleanQueryで検索にヒットするはずのドキュメントが漏れる不具合が先日リリースされたばかりの2.9.0で発覚した。同じテストコードは2.4.1では出ないので、2.9.0で新たに入り込んだバグである。すでに修正され、2.9.1に含まれる。2.9.1にはFastVectorHighlighterの修正も含まれる。
BooleanQueryの不具合 https://issues.apache.org/jira/browse/LUCENE-1974 FastVectorHighlighterの不具合 https://issues.apache.org/jira/browse/LUCENE-1953 Solr 1.4はRCを現在準備中だが、Lucene 2.9.1を取り込む予定である。 2009.10.13 Tuesday
ほぼリアルタイムサーチの不具合
ほぼリアルタイムサーチ(NRT)はLucene 2.9に新しく加わった機能で、IndexWriterにgetReader()メソッドを持たせ、そのメソッドを使って取得したIndexReaderを使えば、それまでにIndexWriterに追加した未コミットの文書も検索対象にできる、というものである。
このNRTで取得したIndexReaderに不具合が報告された: https://issues.apache.org/jira/browse/LUCENE-1976 NRTで取得したIndexReaderのisCurrent()とgetVersion()メソッドが正しい値を返さない、というのが不具合の内容である。現在はisCurrent()は常にtrueを返してしまい、getVersion()は最後のコミット時点のバージョンを返してしまう。 修正のアイディアとしては、isCurrent()についてはgetReader()よりあとにインデックスに変更があった場合はfalseを、そうでないときはtrueを返す。また、getVersion()についてはgetReader()を呼び出した時点でいいのではないか、とレポーターのMikeは言っている。 このNRTの不具合は検索自体は問題なく動作するので、ほとんどのNRTを利用しているアプリケーションはすぐに何か対応しなければならないということはないと思われる。 この不具合の修正は今のところ3.1に予定されている。Lucene 2.9を出したばかりのコミュニティでは現在、Lucene 3.0のリリースに向けた作業の真っ最中である。Lucene 3.0では2.Xのdeprecated APIが削除されるため、皆、「消す作業は楽しい!!」などといいながら激しいコミットログを日々飛ばしている。 2009.10.13 Tuesday
(off topic)(メモ)svnコミットログの修正方法
Solrの不具合修正のコミットログを間違えてあせった。修正方法をメモしておく:
# まちがったコミットログのリビジョン番号を確認 $ svn log 修正をコミットしたファイル # 上で得たリビジョン番号(824380とする)を指定してログメッセージを修正 $ svn propset --revprop -r 824380 svn:log "SOLR-670: Rollback should reset not only adds/deletesById/deletesByQuery counts but also cumulative counts of them." コミットログを失敗した同じコンソールのワーキングコピーにて上記の通り操作する。コミットは不要で上の通り実行すればいきなり書き換わる。 (参考)http://svnbook.red-bean.com/en/1.1/re23.html 2009.10.10 Saturday
インデックス分割ツール IndexSplitter (3.0)
インデックスを分割するツールが今開発中のLucene 3.0に入った:
https://issues.apache.org/jira/browse/LUCENE-1959 ツールはNRT(ほぼリアルタイム)作者のJasonさんが提案したIndexSplitter(本日時点でコミット済み)と、それに反応してLuke作者のAndrzejさんが提案したMultiPassIndexSplitter(本日時点で未コミットだが入る模様)の2種類が含まれており、独立に動作する。 どちらもlucene-misc-3.0-dev.jarに入っているので、起動するにはこのJARファイルとlucene-core-3.0.jarをクラスパスに入れればよい。以下簡単にこれらのツールを紹介しよう。 IndexSplitter IndexSplitterは、分割元のインデックスが複数セグメントであることを前提としたツールである。 使い方は、次のように引数なしで実行するとヘルプが表示される: $ java -cp lib/lucene-core-3.0-dev.jar:lib/lucene-misc-3.0-dev.jar org.apache.lucene.index.IndexSplitter Usage: IndexSplitter そこでまず、-lオプションを使って分割元のindexディレクトリのセグメントを表示してみる: $ java -cp lib/lucene-core-3.0-dev.jar:lib/lucene-misc-3.0-dev.jar org.apache.lucene.index.IndexSplitter index -l _vg 240 _vh 240 _vi 240 次に、_vhと_viのファイルをdestIndexディレクトリに移動する。この時点ではまだ分割元のインデックスディレクトリにセグメントファイルは残ったままである: $ java -cp lib/lucene-core-3.0-dev.jar:lib/lucene-misc-3.0-dev.jar org.apache.lucene.index.IndexSplitter index destIndex _vh _vi $ ls -l index total 40 -rw-r--r-- 1 koji staff 240 10 10 12:58 _vg.cfs -rw-r--r-- 1 koji staff 240 10 10 12:58 _vh.cfs -rw-r--r-- 1 koji staff 240 10 10 12:58 _vi.cfs -rw-r--r-- 1 koji staff 20 10 10 12:58 segments.gen -rw-r--r-- 1 koji staff 599 10 10 12:58 segments_3q $ ls -l destIndex total 32 -rw-r--r-- 1 koji staff 240 10 10 13:15 _vh.cfs -rw-r--r-- 1 koji staff 240 10 10 13:15 _vi.cfs -rw-r--r-- 1 koji staff 20 10 10 13:15 segments.gen -rw-r--r-- 1 koji staff 410 10 10 13:15 segments_1 最後に、元のインデックスディレクトリに残ったままの_vhと_viのセグメントファイルを削除する。indexディレクトリの中を確認するとセグメントファイルとしては残っているが、新しいsegements_Nファイルができており、Luceneプログラムを作って中身を確認すれば、きちんと移動できていることがわかる: $ java -cp lib/lucene-core-3.0-dev.jar:lib/lucene-misc-3.0-dev.jar org.apache.lucene.index.IndexSplitter index -d _vh _vi $ ls -l index total 48 -rw-r--r-- 1 koji staff 240 10 10 12:58 _vg.cfs -rw-r--r-- 1 koji staff 240 10 10 12:58 _vh.cfs -rw-r--r-- 1 koji staff 240 10 10 12:58 _vi.cfs -rw-r--r-- 1 koji staff 20 10 10 13:18 segments.gen -rw-r--r-- 1 koji staff 599 10 10 12:58 segments_3q -rw-r--r-- 1 koji staff 221 10 10 13:18 segments_3r MultiPassIndexSplitter MultiPassIndexSplitterは分割元のインデックス(=入力インデックス)が複数セグメントであることを前提とはしていない。また、出力インデックスとして2つ以上のインデックスを指定して、入力インデックスを複数の出力インデックスに出力する。 MultiPassIndexSplitterの使い方も、引数なしで起動すればヘルプが表示される: $ java -cp lib/lucene-core-3.0-dev.jar:lib/lucene-misc-3.0-dev.jar org.apache.lucene.index.MultiPassIndexSplitter Usage: MultiPassIndexSplitter -out <outputDir> -num <numParts> [-seq] <inputIndex1> [<inputIndex2 ...] inputIndex path to input index, multiple values are ok -out ouputDir path to output directory to contain partial indexes -num numParts number of parts to produce -seq sequential docid-range split (default is round-robin) -outの後ろに出力インデックスディレクトリの親ディレクトリを指定し、-numの後ろに出力するインデックス数を指定する(2以上でなければならない)。そして入力インデックスとして少なくとも1つの入力インデックスディレクトリ名を指定する。以上が必須のパラメータとなる。 さらに-seqを指定すると、出力インデックスへはそれぞれ連続したdocidのドキュメントが出力される。たとえば、入力インデックスにdocid=[0,1,2,3,4,5,6,7,8]のドキュメントがあり、-numに3を指定した場合、-seqとすると、3つの出力インデックスはそれぞれ、[0,1,2], [3,4,5], [6,7,8]のdocidとなる。 -seqを指定しないときのデフォルトは、ラウンドロビンであり、3つの出力インデックスはそれぞれ、[0,3,6], [1,4,7], [2,5,8]のdocidとなる。 IndexSplitter、MultiPassIndexSplitterともpublicなsplit()というインスタンスメソッドを持ち、適切なパラメータを渡せばAPIとしても使うことができる。 |
+ Solrによるブログ内検索
+ PROFILE
+ LINKS
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
+ RECOMMEND
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
+ SPONSORED LINKS
|
(C) 2024 ブログ JUGEM Some Rights Reserved.
|
PAGE TOP |