這個東西在2006年初,我就開始在項目中使用.我對它也有了一些了解. 但因為主要開發還是小兵們在做. 所以僅僅了解了一些皮毛. 下面我將以知識點的形式, 列出來. 以筆記的形式連載. 也方便大家一起學習. 每一個點, 我都會寫一個知識點.

1, 2005年的時候, 聽說了lucene. 是一個開源的搜索引擎開發包. 而不是一個搜索引擎,請切記.
2, 如果開始學習它, 就需要至少知道,它所包含的包. 目前lucene已經到了2.2版本. 當然你需要時刻關注他的最新版本. 目前包: lucene-core-2.2.0.jar . 下載可以到apache的網站上下載. 這一個就夠了.不用下別的.
3, 下面問題會接踵而至, 我挨著寫,你挨著看即可.
分詞. 第一個要涉及的問題, 分詞就是將一句話中的關鍵詞匯分離出來, 然后才可以建立索引. 例如 中華人民共和國 --> 中華, 中華人民 華人,人民, 共和國,等. lucene缺省帶了一個標準分詞的類: StandardAnalyzer 這個按字來分的. 從網上發現了很多程序員寫的開源的分詞的類. 當然都是繼承了lucene的org.apache.lucene.analysis.Analyze類. 以實現更好更快的分詞效果. 可以搜索獲取更多, 一般分詞的類,都提供了可檢測分詞效果的方法. 輸入一個長句, 然后執行,看看分詞效果和執行時間.

4, ThesaurusAnalyzer是一個哥們開發的,網上有源碼可以下載. 從這個源碼里面對分詞可以有更深入的了解: 包括那些是詞匯,那些不是詞匯. 都在文本文件里面以行分割開來. 由此可以知道: 分詞是需要詞庫的. 因為詞庫可以不斷的擴充 .但每次構造分詞對象時,是建立在當前詞庫基礎上的. 如果詞庫動態增加了新的詞匯, 需要重新構建分詞對象. 當然, 也可以讀取數據庫.

5, 上面的分詞, 也僅僅是分詞! 網上有人提出的問題是: 索引中,加入了"東北大學". "北大" . 要搜索 北大 , 顯然我們沒有找到東北大學的意思. 但最后還是找到了. 因為東北大學四個字里面有北大兩個字. 分詞時這個詞被確認是個詞, 就加入了索引. 這種情況, 涉及到漢語語義的問題 .暫時不好解決. 所以不提.

選擇較好的分析器
這個優化主要是對磁盤空間的優化,可以將索引文件減小將近一半,相同測試數據下由600M減少到380M。但是對時間并沒有什么幫助,甚至會需要更長時 間,因為較好的分析器需要匹配詞庫,會消耗更多cpu,測試數據用StandardAnalyzer耗時133分鐘;用MMAnalyzer耗時150分 鐘。


6, 分詞的缺失: 就似乎同義詞. 為了減少用戶搜索的次數, 增加搜索效果. 如果用戶搜 "北京 飯店" 能不能把" 首都 飯店"也列出來呢. 這個分詞器無能為力. 我也考慮到這個問題, 在北京托爾四公司的TRS的搜索產品文檔中人家也考慮到了這個問題. 就似乎如果搜索 銳器, 系統會自動把匕首,尖刀等詞匯一并加入搜索結果. 所以這個問題 ,就只能是在分詞之前,我們再加一層:同義詞返回模塊. 這個思路很不錯, 也比較簡單. 很容易實現. 關鍵是詞庫的建立. 這個就說到這里.

7, 說到這里,你可能想要做個例子來實踐一下. 做個例子很容易. 網上很多. 我只做簡單的敘述: lucene是用目錄或者內存來存儲數據的. 可以設定. 但是實踐證明RAMDirectory和FSDirectory速度差不多,當數據量很小時兩者都非常快,當數據量較大時(索引文件 400M)RAMDirectory甚至比FSDirectory還要慢一點,這確實讓人出乎意料。
而且lucene的搜索非常耗內存,即使將400M的索引文件載入內存,在運行一段時間后都會out of memory,所以個人認為載入內存的作用并不大。
我們用目錄:
如下:
//構建一個 IndexWriter 用來寫如索引
File indexDir = new File(
"E:""javasource""LuceneTest""index");

IndexWriter indexWriter = new IndexWriter(indexDir,
new ThesaurusAnalyzer(), false);
Document doc = Document(new Article("name"+i, "北京老張"));
indexWriter.addDocument(doc);
indexWrite.close();

由上可以看出, lucene將在這個目錄下進行操作. 上面代碼中的你不要抄襲當例子, 因為還有一個Article類和Document方法.里面也有一些東西. 現在僅僅先理解上面的意思即可. 操作前,你可能不知道他會在目錄里干什么.

8, 目錄下的東西 . 如果測試成功, 目錄下有三個文件.
segments.gen segments_a08, 還有一個類似 _uw.cfs名字的東西. 當然,不一定都一樣, 但肯定是這三個. 如果出現了很多文件.不要著急, 看下面的 9 .

9, 如果lucene的索引目錄下出現了很多文件, 肯定是有問題的. 幾個方面.首先lucene在執行寫操作時, 會先在目錄下寫如一個write.lock的文件鎖定這個目錄,以避免別的索引再操作這個路徑. 否則那樣肯定會亂. 鎖定之后, 開始寫索引, 寫索引時lucene建了幾個或者幾十個臨時片段文件, 都似乎又短又亂的字符.cfs的文件. 當索引建立完畢后,沒有執行 indexWriter.optimize();方法, 他就不會合并那些亂七八糟的文件. 所以,索引建完后, 一定要執行 上面的優化方法, 保持目錄下保留3個文件即可. 也就是很多臨時文件會合并到一個文件中去. 切不可大意刪除. 但當數據很多時, 另行考慮策略.

10, lucene在寫入索引時, 用在索引目錄下建write.lock文件來標識鎖定. 而只有在執行close()方法后, 才會刪除這個鎖文件. 只要這個文件存在, 其他的寫索引的程序都會報錯:
caught a class org.apache.lucene.store.LockObtainFailedException
with message: Lock obtain timed out: SimpleFSLock@E:"javasource"LuceneTest"index"write.lock

所以,需要注意, 一定要注意關閉indexWrite. 包括異常下,用finally關閉.否則會導致下一次寫索引失敗.

11, 批量增加索引, 如果要成批的用循環加入索引,該怎么辦呢. 首先請注意: IndexWriter indexWriter = new IndexWriter(indexDir,
new ThesaurusAnalyzer(), false); 最后一個參數為false表示持續想索引增加數據. 如果為true, 則每次會刪除全部, 重新開始.

12, 在批量增加索引時, 程序可以一直執行
indexWriter.addDocument(doc); 但不能一直執行優化:indexWriter.optimize(); 因為優化方法比較耗時, 特別是當索引很大時, 更要注意. 因為優化, 也僅僅似乎優化會消耗很多時間和cpu. 所以這個時候.多幾個文件也沒關系. 網上有個人問了這樣的問題, 我摘錄如下, 用等號分割開我的內容:
引自:
http://www.javaeye.com/topic/107818?page=3
================================================
我不知道是不是理解錯了增量索引的概念
我搜索的網頁不會重復,不是對所有的網頁都不停的搜,而是我搜索特定的網站.這里面不會出現重復現象.每次爬到的網頁肯定是index里沒有的

問一個問題
如果有10個網頁需要建立index

IndexWriter iw=new IndexWriter(...);
for(int i=0;i<10;i++){
iw.addDocuemnt(doc);
}
iw.close();

還是
for(int i=0;i<10;i++){
IndexWriter iw=new IndexWriter(...);
iw.addDocuemnt(doc);
iw.close();
}

還有,如果index量有10G,做一次optimize需要多長時間?
建議多長時間Optimize一次?
對一個剛剛做過Optimize的index目錄做Optimize,會不會很快就結束,還是也需要很長時間?
optimize結束后是不是只剩下3個文件?如果有其他文件,是不是意味著有問題呢?(沒有Reader或者Searcher在使用這個index的時候)



返回頂端 最后更新: 2007-08-10 11:02 (0) (0) 正在投票中...


amigobot 等級: 初級會員

文章: 28
積分: 14

時間: 2007-08-12 14:15 引用 收藏

--------------------------------------------------------------------------------

沒有必要6分鐘一次。 每次optimize都會重新做索引, 光拷貝10G文件就得多少分鐘?如果不是頻繁刪除的話, 一天, 甚至一禮拜一趟都可以。 選擇系統負載少的時候就行。



返回頂端 最后更新: 2007-08-12 14:15 (0) (0) 正在投票中...


licco1 等級: 初級會員

文章: 22
積分: 0

時間: 2007-09-06 09:43 引用 收藏

--------------------------------------------------------------------------------

1:當search動作太頻繁,或者訪問的人很多,在optimize時會出現這個message
java.io.IOException: Cannot delete E:"index"_nir.f2;
注意檢查下是不是每次查詢完都把indexReader給close了。你可以測試下,頻繁的開search,如果還有這個異常,估計就是沒把 indexReader給close(千萬不要以為close the indexSearcher 就ok了,要注意新建indexSearcher時傳的參數是什么,是Direcitory,還是indexReader,還是字符串文件路徑,這影響是 否close indexReader)



返回頂端 最后更新: 2007-09-06 09:43 (0) (0) 正在投票中...


fool_leave 等級: 初級會員

性別:
文章: 21
積分: 0
來自: 上海

時間: 2007-09-07 09:44 引用 收藏

--------------------------------------------------------------------------------

新建indexReader時傳入的是index file path,而且在search完畢后都在finally里面做了close動作。

BTW:我把optimize動作去掉后,也就是說無論它運行多久都不讓他optimze,結果index很正常,文件數量不會增加很多,search也okay。

問題是總不能老這樣呀,一直不optimize也不行呀。我做一次optimize,就要n分鐘,index文件太大,沒辦法。

而且我的index動作是針對不同的網頁,比如http://xxx.xxx.xxx/1.html被index后,以后遇到這個頁面就不會再做index動作。換句話說,每次index的內容都是新的,不會覆蓋以前的東西。這樣的需求是不是不用optimize呀。



返回頂端 最后更新: 2007-09-07 09:44 (0) (0) 正在投票中...


licco1 等級: 初級會員

文章: 22
積分: 0

時間: 2007-09-07 10:09 引用 收藏

--------------------------------------------------------------------------------

fool_leave,你用的lucene版本是多少?如果是2.2的話,可以用indexwriter;以前用2.0,我用indexReader執行 刪除操作也出現過類似的情況(懷疑是indexreader只將被刪除的documents設置了下刪除的標志,在close的時候沒真正執行刪除動作, 也許是我少執行了一個步驟,=會去看看reader的刪除操作)。如果因為文件太大導致優化(optimze,它的作用是重新整理段,把document 的id重新設置,這個對搜索效率很有幫助,和document里term的內容沒關系)的時間很長,那就得重新考慮下你的架構了(10g太大了)。這個得 請教下imjl.



返回頂端 最后更新: 2007-09-07 10:12 (0) (0) 正在投票中...


dwangel 等級:

文章: 500
積分: 650
圈子: TODOtree-ruby

時間: 2007-09-07 12:38 引用 收藏

--------------------------------------------------------------------------------

建議設置時間任務,凌晨2點啟動indexWriter進行optimise。
啟動前前臺頁面切換到顯示維護的狀態,然后等待所有的reader,searcher關閉,然后進行optimise。(當然只有一個writer在跑)

In environments with frequent updates, optimize is best done during low volume times, if at all.
摘自lucene的文檔
http://lucene.zones.apache.org:8080/hudson/job/Lucene-Nightly/javadoc/org/apache/lucene/index/IndexWriter.html#optimize()

It is best not to re-open readers while optimize is running.
這句話我不是很明白,我覺得應該是說不要在optimize運行時打開新的reader。但是用的re-open,難道是說
不要在optimize時,重置reader。的狀態?



返回頂端 最后更新: 2007-09-07 12:48 (0) (0) 正在投票中...


licco1 等級: 初級會員

文章: 22
積分: 0

時間: 2007-09-07 17:29 引用 收藏

--------------------------------------------------------------------------------

因為if some but not all readers re-open while the optimize is underway, this will cause > 2X temporary space to be consumed as those new readers will then hold open the partially optimized segments at that time.所以It is best not to re-open readers while optimize is running.在進行優化的時候最好不要新開readers(2.2里好像沒有reopen這個方法吧,2.3里估計會出),因為新的readers同 時會打開部分優化過的段,索引耗損的臨時空間會大于兩倍索引大小(翻譯錯了樓下的一定要指出來哦)。

我覺得在做優化時,不會對searcher有影響,不必關閉搜索功能。



返回頂端 最后更新: 2007-09-07 17:31 (0) (0) 正在投票中...


fool_leave 等級: 初級會員

性別:
文章: 21
積分: 0
來自: 上海

時間: 2007-09-10 09:56 引用 收藏

--------------------------------------------------------------------------------

thanks
無論是不是reopen,optimize都會耗用更多的space來存儲臨時文件.但這些都是臨時文件,在動作結束后會被釋放掉.所以如果硬盤空間足夠,這些多余的耗用應該不是大問題。

但我的index目錄總共有3G(我把舊的document刪除了)。不過每次optimize一樣要花費很長時間。我不知道應該如何重新設置document的id.我的lucene version是2.0的。

lucene的optimize的結果除了將index的文件數變成3個,還有什么好處呢?到現在我看來只有在delete索引節點后有必要通過 optimize真正的把這些節點刪除,其他的優勢似乎非常不明顯。(因為我每次寫入index的索引內容都是新的,不會有重復或追加現象)。我現在徹底 把optimize從程序里去掉了,運行到現在已經1個月了,每分鐘都有新內容加進去,但index目錄依然很正常,文件數24個,從文件的修改時間上來 看也很正常。search動作也很正常。

如果一次optimize需要花費5分鐘以上的時間,而這個操作又是不可中斷的,一旦在optimize過程中終止了程序,就會出現lucene自身無法恢復問題。這樣對于程序要求太高了。對于服務器管理也要求太高了。

=========================================
上面的內容有些多, 不過也對大家有益. 他說最后他把執行優化的代碼去掉了,運行很好. 對于大數據量的來說, 這是個經驗. 除非采用冗余的機制, 而不能對正在使用的數據進行優化操作. 會造成用戶訪問阻塞.

由上面可見的, 我就不說了.
13, 索引過程中的任意時刻、任意進程都能對索引文件進行優化,而且這樣做也不會損壞索引文件或使其不能被搜索,但是在索引過程中對索引進行優化的做法并不值得 提倡。優化操作的最佳時機是在索引過程結束之后,且當你確認在此后的一段時間內不會對索引文件進行更改的時候。在索引過程中進行優化只會使優化操作耗費更 多的時間。(請大家汲取這個思想)



14, 還是優化, 些人問: 我用lucene做了一個Search Engine
程序運行也很正常,但如果連續運行幾個月,有時會出現磁盤空間不足的情況 .
通過iw.addDocument(doc)寫入index
當list里的東西全部被寫入完畢后,通過optimze來優化索引,
可這個東西運行不是很穩定,有的時候很正常,運行幾個月都okay,有時1個月就出現問題了。會在index的目錄里出現很多文件。這些文件似乎是應該被 optimize掉的。 一個索引只能有一個indexreader, 在optimize的時候可以有多個indexsearcher在工作。
你得確保
-->optimize確實調用了
-->optimize的時候, 得有雙倍的磁盤空間. 可見優化的代價.



15 ,面的lucene都是在一個目錄里面的, 大家也都看到了. 也就是如果這個文件一直很大怎么辦. 首先碰到的第一個問題是就是文件大小限制. 首先面臨的是一個大目錄問題.

16, lucene的性能測試:
下面給出一些測試數據,如果你覺得可以接受,那么可以選擇。
測試一:250萬記錄,300M左右文本,生成索引380M左右,800線程下平均處理時間300ms。
測試二:37000記錄,索引數據庫中的兩個varchar字段,索引文件2.6M,800線程下平均處理時間1.5ms。


17 . 分布搜索

我們可以使用 MultiReader 或 MultiSearcher 搜索多個索引庫。

MultiReader reader = new MultiReader(new IndexReader[] { IndexReader.Open(@"c:"index"), IndexReader.Open(@"""server"index") });
IndexSearcher searcher = new IndexSearcher(reader);
Hits hits = searcher.Search(query);



IndexSearcher searcher1 = new IndexSearcher(reader1);
IndexSearcher searcher2 = new IndexSearcher(reader2);
MultiSearcher searcher = new MultiSearcher(new Searchable[] { searcher1, searcher2 });
Hits hits = searcher.Search(query);

還可以使用 ParallelMultiSearcher 進行多線程并行搜索。

18. 合并索引庫

將 directory1 合并到 directory2 中。
Directory directory1 = FSDirectory.GetDirectory("index1", false);
Directory directory2 = FSDirectory.GetDirectory("index2", false);

IndexWriter writer = new IndexWriter(directory2, analyzer, false);
writer.AddIndexes(new Directory[] { directory });
Console.WriteLine(writer.DocCount());
writer.Close();

19. 顯示搜索語法字符串

我們組合了很多種搜索條件,或許想看看與其對等的搜索語法串是什么樣的。
BooleanQuery query = new BooleanQuery();
query.Add(query1, true, false);
query.Add(query2, true, false);
//...

Console.WriteLine("Syntax: {0}", query.ToString());

輸出:
Syntax: +(name:name* value:name*) +number:[0000000000000000b TO 0000000000000000d]

呵呵,就這么簡單。

20. 操作索引庫

刪除 (軟刪除,僅添加了刪除標記。調用 IndexWriter.Optimize() 后真正刪除。)
IndexReader reader = IndexReader.Open(directory);

// 刪除指定序號(DocId)的 Document。
reader.Delete(123);

// 刪除包含指定 Term 的 Document。
reader.Delete(new Term(FieldValue, "Hello"));

// 恢復軟刪除。
reader.UndeleteAll();

reader.Close();

增量更新 (只需將 create 參數設為 false,即可往現有索引庫添加新數據。)
Directory directory = FSDirectory.GetDirectory("index", false);
IndexWriter writer = new IndexWriter(directory, analyzer, false);
writer.AddDocument(doc1);
writer.AddDocument(doc2);
writer.Optimize();
writer.Close();

21. 優化

批量向 FSDirectory 增加索引時,增大合并因子(mergeFactor )和最小文檔合并數(minMergeDocs)有助于提高性能,減少索引時間。

IndexWriter writer = new IndexWriter(directory, analyzer, true);

writer.maxFieldLength = 1000; // 字段最大長度
writer.mergeFactor = 1000;
writer.minMergeDocs = 1000;

for (int i = 0; i < 10000; i++)
{
// Add Documentes...
}

writer.Optimize();
writer.Close();

相關參數說明


轉自《深入 Lucene 索引機制》

利用 Lucene,在創建索引的工程中你可以充分利用機器的硬件資源來提高索引的效率。當你需要索引大量的文件時,你會注意到索引過程的瓶頸是在往磁盤上寫索 引文件的過程中。為了解決這個問題, Lucene 在內存中持有一塊緩沖區。但我們如何控制 Lucene 的緩沖區呢?幸運的是,Lucene 的類 IndexWriter 提供了三個參數用來調整緩沖區的大小以及往磁盤上寫索引文件的頻率。

22.合并因子 (mergeFactor)

這個參數決定了在 Lucene 的一個索引塊中可以存放多少文檔以及把磁盤上的索引塊合并成一個大的索引塊的頻率。比如,如果合并因子的值是 10,那么當內存中的文檔數達到 10 的時候所有的文檔都必須寫到磁盤上的一個新的索引塊中。并且,如果磁盤上的索引塊的隔數達到 10 的話,這 10 個索引塊會被合并成一個新的索引塊。這個參數的默認值是 10,如果需要索引的文檔數非常多的話這個值將是非常不合適的。對批處理的索引來講,為這個參數賦一個比較大的值會得到比較好的索引效果。

23.最小合并文檔數 (minMergeDocs)

這個參數也會影響索引的性能。它決定了內存中的文檔數至少達到多少才能將它們寫回磁盤。這個參數的默認值是10,如果你有足夠的內存,那么將這個值盡量設的比較大一些將會顯著的提高索引性能。

24.最大合并文檔數 (maxMergeDocs)

這個參數決定了一個索引塊中的最大的文檔數。它的默認值是 Integer.MAX_VALUE,將這個參數設置為比較大的值可以提高索引效率和檢索速度,由于該參數的默認值是整型的最大值,所以我們一般不需要改動這個參數。

25 , 根據官方文檔:從中可以分析出,如果在optimize索引的時候,也同時使用Searcher。索引空間的使用情況如下:
1. 原始索引
2. 由IndexWriter使用的索引,用于optimize
3. 由IndexSearcher使用的索引,用于搜索。

所以要三倍的正常空間.

為什么需要優化?
盡管未經優化的索引在大多數應用程序中都能夠很好地進行工作,但在那些處理大批量索引的應用程序中,使用優化過的索引會給應用程序帶來更多的好處。特別是 在搜索操作需要長時間打開多個索引文件的情況下,更能體現出索引被優化后的優勢,因為使用優化過的索引可以減少需要打開的文件描述符的個數

優化所需的磁盤空間
值得指出的是,Lucene對一個索引的優化操作是通過把已存在的段合并成一個全新的段來完成的,這些已存在段的內容最終會在新的段中表示出來。因而在進 行優化時,使用的磁盤空間會有明顯的增加。在新段創建完成時,Lucene刪除并移除這些舊段。因此,在舊的段還沒有被刪除之前,索引占用的磁盤空間會變 成原來的兩倍,因為此時新段和舊段都會存儲在索引中。在優化完成后,所占用的磁盤空間會降回到優化前的狀態。請記住,索引優化的對象可以是多文件索引或復 合索引。



26 , 索引文件有大小限制嗎?(翻譯)

某些 32 位操作系統限制每個文件不能大于 2GB。

解決方法:
1. 使用 IndexWriter.setMaxMergeDocs() 減小 MaxMergeDocs 數值。
2. 使用多個索引庫。使用復合索引.


27, IndexWriter.SetUseCompoundFile(true) 有什么用?

在創建索引庫時,會合并多個 Segments 文件到一個 .cfs 中。此方式有助于減少索引文件數量,減少同時打開的文件數量。原因:
某些操作系統會限制同時打開的文件數量。

解決方法:
1. 使用 IndexWriter's setUseCompoundFile(true) 創建復合文件,減少索引文件數量。
2. 不要將 IndexWriter's mergeFactor 的值設置過大。盡管這能加快索引速度,但會增加同時打開的文件數量。
3. 如果在搜索時發生該錯誤,那么你最好調用 IndexWriter.Optimize() 優化你的索引庫。
4. 確認你僅創建了一個 IndexSearcher 實例,并且在所有的搜索線程中共用。(原文:"Make sure you only open one IndexSearcher, and share it among all of the threads that are doing searches -- this is safe, and it will minimize the number of files that are open concurently. " 暈~~~,究竟要怎么做? )

28, 為什么搜索不到結果?(翻譯)

可能原因:
. 搜索字段沒有被索引。
. 索引庫中的字段沒有分詞存儲,無法和搜索詞語進行局部匹配。
. 搜索字段不存在。
. 搜索字段名錯誤,注意字段名稱區分大小寫。建議對字段名進行常量定義。
. 要搜索的詞語是忽略詞(StopWords)。
. 索引(IndexWriter)和搜索(IndexSearcher)所使用的 Analyzer 不同。
. 你所使用的 Analyzer 區分大小寫。比如它使用了 LowerCaseFilter,而你輸入的查詢詞和目標大小寫不同。
. 你索引的文檔(Document)太大。Lucene 為避免造成內存不足(OutOfMemory),缺省僅索引前10000個詞語(Term)。可以使用 IndexWriter.setMaxFieldLength() 調整。
. 確認在搜索前,目標文檔已經被添加到索引庫。
. 如果你使用了 QueryParser,它可能并沒有按照你所設想的去分析 BooleanQuerySyntax。

如果還不行,那么:

. 使用 Query.ToString() 查看究竟搜索了些什么。
. 使用 Luke 看看你的索引庫究竟有什么。

29, 上面的luke是查看索引庫的, 我下載了一個版本, 居然總提示我給他的索引路徑不對.無奈. .

30 ,

QueryParser 是線程安全的嗎?

不是。

31, 說說分布式數據存儲. 支持lucene的分布式搜索就是 hadoop. 這個也是apache下的屬于lucene的開源項目. 但目前的我看只支持linux的分布機器. 網上很多這個方面的. 據說開發hadoop的人已經去了yahoo. 讓hadoop支撐雅虎的分布式搜索. 所以按說功能強大.2006年的一月份Nutch和Lucene的締造者Doug Cutting加入了Yahoo公司,從那時起,Yahoo就開始進行Hadoop的部署與研究. 但網上有人說, 這個分布式效率不高.

參數如下:

經測試,Hadoop并不是萬用靈丹,很取決于文件的大小和數量,處理的復雜度以及群集機器的數量,相連的帶寬,當以上四者并不大時,hadoop優勢并不明顯。
比如,不用hadoop用java寫的簡單grep函數處理100M的log文件只要4秒,用了hadoop local的方式運行是14秒,用了hadoop單機集群的方式是30秒,用雙機集群10M網口的話更慢,慢到不好意思說出來的地步。

評: 怎么評價上面的哥們測試結果呢. 但愿他說的不對. 因為如果這樣, yahoo不就死了..

32, MaxDoc() 和 DocCount()、NumDocs() 有什么不同?

MaxDocs() 表示索引庫中最大的 Document ID 號,由于中間的某些 Document 可能被刪除,因此不能使用 MaxDocs() 來表示 Document 數量。IndexWriter.DocCount()、IndexReader.NumDocs()、 IndexSearcher.Reader.NumDocs() 都表示索引庫中 Document 數量。

33, 為什么同時進行搜索和更新會引發 FileNotFoundException 異常?(翻譯)

可能原因:
1. 某個搜索或更新對象禁用了鎖。
2. 搜索和更新使用了不同的 lockDir。
3. 索引庫被存放在 NFS (or Samba) 文件系統上。

盡管搜索是只讀操作,但 IndexSeacher 為了獲取索引文件列表,也必須打開時鎖定索引庫。如果鎖沒有正確設置,那么它將取回一個錯誤的文件列表(此時 IndexWriter 可能正在添加或優化索引),從而導致該異常發生。

34, write.lock 有什么用?哪些類會用到它?(翻譯)

write.lock 用來協調索引庫的并發修改處理。
當 IndexWriter 打開索引庫,或者 IndexReader 刪除文檔時都將創建該鎖。

35. commit.lock 文件有什么用?哪些類會用到它?(翻譯)

commit.lock 在調整索引庫 segments 文件內容時使用。 IndexReader 和 IndexWriter 都會使用到它。

36, 如何更新已經索引的文檔? (翻譯)

你只能先刪除,然后添加更新后的文檔。

使用 IndexWriter.addIndexes(IndexReader[]) 和 IndexWriter.addIndexes(Directory[]) 合并索引庫有什么不同? (翻譯)

使用 Directory[] 參數所需的文件句柄和內存較小,索引文件僅需打開一次,而使用 IndexReader[] 參數則需要打開所有的索引庫。

ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程