2011-10-08 45 views
5

我們對Sitecore的6.4和正在使用的共享源代碼高級搜索模塊,並看到在站點搜索性能有很大降解當Sitecore的重新索引化處理踢和更新的變化到網絡數據庫。Sitecore的搜索性能時重新索引和定製IndexingProvider

當我們揭開序幕,一個完整的網站發佈,索引經理拿起變化和處理歷史記錄,這反過來又重新索引中的每個已受影響的項目。由於這發生在每個項目中,您可以看到磁盤上的Lucene索引在查看目錄時發生了變化(文件的數量隨着您的觀察而增長和變化)。

如果你試圖當發生這種情況的公共網站上搜索時,搜索可以採取noticibly較長時間才能完成;並且在重負荷下它可能需要長達15秒的時間,直到重新索引過程結束。

我可以看到這個過程是由IndexingProvider類控制的。有什麼方法來重寫這個類並實現我們自己的?

我們已經看了搜索邏輯和可以看到的IndexSearchContext對象創建的每個搜索請求的時間,這反過來又創造了新的IndexSearcher的。我們改變了一些邏輯,以便將IndexSearchContext保存爲單例,這當然意味着可以由同一個Lucene IndexSearcher提供多個請求。這大大降低了內存消耗,因爲建議使用相同的搜索器來提高性能。

但是,在這種情況下,只有在創建新的IndexSearcher之前,纔會檢索對索引的更改。我們需要一種方法來通知我們的代碼索引過程已經完成,然後我們可以重置我們的單例IndexSearchContext對象。我們如何將這個邏輯集成到Sitecore配置的代碼中?

手動重建索引時,只需約5秒即可完成。顯然,這有效地刪除了索引,然後再次創建它,但爲什麼逐項更新需要很長時間?沒有更好的方法可以實現更新過程而無需逐項進行,並且不會影響公共網站?

我本來期望別人受此問題影響,因此我渴望聽到人們如何解決這個問題。

編輯 - 從Sitecore的論壇

附加信息的Sitecore.Search代碼似乎確實大量使用創造了一個單一的操作/配置新的Lucene的對象。它對於大型環境來說似乎不是過度可擴展的,這就是爲什麼當我看到代碼時我很驚訝。特別是如果索引很大,並且每天都有很多內容更新/發佈。在通過dotPeek類

尋找我看不到,因爲它是在非虛方法創建我們如何覆蓋IndexUpdateContext。自定義DatabaseCrawler可以獲得一些訪問權限,但只能訪問已創建的上下文對象。

我注意到我們可以在web.config中爲每個索引定義我們自己的索引實現。我們也可以重新實現抓取工具(我們已經從共享模塊中獲得了高級抓取工具),也許可以控制索引過程。我不願意將太多Sitecore代碼放入我們自己的實現中,因爲它可能會影響將來的更新。

雖然我有一個關於IndexingProvider的問題。在下面的方法:

private void UpdateItem(HistoryEntry entry, Database database) 
    { 
     int count = database.Indexes.Count; 
     if (count != 0 || this.OnUpdateItem != null) 
     { 
     Item obj = database.GetItem(entry.ItemId, entry.ItemLanguage, entry.ItemVersion); 
     if (obj != null) 
     { 
      if (this.OnUpdateItem != null) 
      this.OnUpdateItem((object) this, (EventArgs) new SitecoreEventArgs("index:updateitem", new object[2] 
      { 
       (object) database, 
       (object) obj 
      }, new EventResult())); 
      for (int index = 0; index < count; ++index) 
      database.Indexes[index].UpdateItem(obj); 
     } 
     } 
    } 

它觸發更新事件,其由DatabaseCrawler,因爲它連接到IndexingProvider.OnUpdateItem事件處理;但爲什麼上面的方法也調用Sitecore.Data.Indexing.Index.UpdateItem方法?我認爲6.5版本的命名空間正在被折舊,所以我很驚訝地發現新命名空間和舊命名空間之間的聯繫。

因此,它看起來像DatabaseCrawler正在處理更新,刪除該項目,然後再次將其添加到索引;然後舊的Sitecore.Data.Indexing.Index也會嘗試更新它。這裏肯定有問題嗎?我不知道,所以如果我錯了,請糾正我的錯誤,這正是我在無需任何調試的情況下追蹤反編譯的代碼時的樣子。

+0

這似乎是先進的(和漂亮整潔的東西)你想這樣做(和迄今所做的)。也許你應該嘗試與Sitecore談論它...如果你有改進,我確定他們喜歡聽到他們:) – Holger

+1

嗨蒂姆,我只能想到這一點,當索引要麼完全重建每個發佈或者你有大量的用戶在做搜索。你是否有大量的遊客或爲重建而特別設置的東西?你可以嘗試禁用索引的更新,然後進行相同的測試嗎?它可能與一般發佈有關,而不僅僅是索引。 –

+0

@Jens,謝謝我們將嘗試禁用索引過程。就內容大小或訪客數量而言,我覺得我們不會做任何不尋常的事情。該網站相對較小。但是我們需要知道性能會不斷擴大。如果索引完全重建,它會更快速地工作,大約5秒鐘完成重建。逐個更新每個項目可能會花費更長的時間,因爲您會形象化。 –

回答

2

我建議兩兩件事:

  1. 使用Advanced Database Crawlerv2是最新的版本),它封裝在Sitecore.Search命名空間。這使得使用Lucene.NET和Sitecore非常容易。

  2. 每天完全重建索​​引。這會對索引進行碎片整理,因爲碎片隨着時間的推移會降低性能(這可能是您的問題)。

+0

我試過使用ADC,它會影響你的解決方案。之後,我將其刪除。 –

1

我遇到過類似的問題。當我分析時,所有時間都在爲每個搜索打開索引。

我們最終解決這個問題的方式是繞過Sitecore的索引類並直接進入Lucene。 Lucene提供了一個「Reopen」方法,它只打開修改後的段文件,而不是像Sitecore那樣的所有段文件。

所以,我們所做的是:

  1. 打開索引讀者,如果我們沒有一個已經
  2. 創建應用程序級別引用它,這樣我們就可以重新使用它
  3. 在每個搜索調用應用指數讀者「重新打開」
  4. 搜索

看一看的Lucene.Net.Index.IndexReader.Reopen我的ThOD Documentation

您可以從Sitecore.Search.Index.CreateReader索引讀卡器()