Sitecore - 负载平衡Lucene查询

时间:2013-10-03 11:06:37

标签: performance lucene sitecore load-balancing sitecore6

Sitecore.NET 6.6.0(rev.130404)

我们的生产网站搜索量非常大,我们的Lucene索引全天都在大量查询。这相当于在Lucene查询处理上花费了大量的CPU功率。是否存在将Lucene索引和查询卸载到其他计算机的行业惯例?或者是否有任何可用于提高Lucene查询性能的硬件机制?

(我们最常用的Lucene索引包含少于10,000个条目)

更新(更多信息):

虽然我们的索引包含的内容少于10,000,但CPU使用率是否会由并行执行的大量Lucene查询引起?我们有一个非常复杂的分面搜索。最初,当用户尝试各种搜索条件时,我们会在所有搜索选项旁边显示结果计数细分(每次搜索请求会产生50-60个计数查询)。这导致高流量时CPU使用率达到90-95%。当我们删除计数时,CPU稳定在20-30%左右。

以下是我们用于查询的两种方法:

    public static Document[] GetLuceneDocuments(ACIndex acIndex, Query query, Sort sort = null, int maxResults = 999, bool trackScores = false, bool fillFields = true)
    {
    Index index = SearchManager.GetIndex(GetIndexName(acIndex));

    if (sort == null)
    {
        sort = new Sort(new SortField(null, SortField.SCORE));
    }

    using (IndexSearchContext searchContext = index.CreateSearchContext())
    {
        Lucene.Net.Search.IndexSearcher searcher = searchContext.Searcher;

        TopFieldCollector collector = TopFieldCollector.create(sort, maxResults, fillFields, trackScores, false, false);
        searcher.Search(query, collector);
        TopDocs topdocs = collector.TopDocs();

        Document[] documents = new Document[topdocs.ScoreDocs.Length];
        for (int i = 0; i < topdocs.ScoreDocs.Length; i++)
        {
            documents[i] = searcher.Doc(topdocs.ScoreDocs[i].doc);
        }

        return documents;
    }
    }

    public static int GetSearchResultCount(ACIndex acIndex, Query query)
    {
        Index index = SearchManager.GetIndex(GetIndexName(acIndex));

        using (IndexSearchContext searchContext = index.CreateSearchContext())
        {
            Lucene.Net.Search.IndexSearcher searcher = searchContext.Searcher;

            TopScoreDocCollector collector = TopScoreDocCollector.create(1, false);
            searcher.Search(query, collector);
            return collector.GetTotalHits();
        }
    }

5 个答案:

答案 0 :(得分:2)

您应该考虑为搜索实施Solr。虽然不是这方面的专家,但Solr基于Lucene(使转换变得更容易)并运行中央服务器或服务器,处理您的所有搜索要求。

在Sitecore 7之前的版本中,Solr在本地不受官方支持 - 但我已经开发了许多使用Solr的Sitecore 6解决方案。

本文应该为您提供一个良好的开端:How to implement Solr into Sitecore

就行业流程而言,使用Sitecore,Solr是解决此特定问题的解决方案。然而,根据您的解决方案实施情况,可能需要做一些工作才能起床和继续。

答案 1 :(得分:0)

您可以在www.alpha-solutions.dk/sitecore-search-solution上查看Siter 6上的Solr方法。 注意:我隶属于Alpha Solutions

答案 2 :(得分:0)

你的索引很小,我知道有建议你重新解析整个解决方案,不过,我建议我过去做过的一些对我有用的东西,并且不要求你配置另一台服务器或安装另一个索引像弹性或SOLR这样的工具。

首先,将字段存储在您所面对的索引中,如下所示(在配置中或使用自定义搜寻器):

  • _group
  • _path
  • _creator
  • 制造商
  • 尺寸
  • ... [其他领域]

创建一个表示结果的类

    public class MyThing
    {
        public string Manufacturer { get; set; }
        public string Size { get; set; }
        public int Year { get; set; }
        public MyThing(Document doc)
        {
            Manufacturer = doc.GetField("Manufacturer").Value;
            Size = doc.GetField("Size").Value;
            Year = int.Parse(doc.GetField("Year").Value);
        }
    }

然后将您的主要搜索结果命中,实例化您的轻量级POCO,并对其进行计数。 Voila,1个查询!

int countForSomething = results.Count(result =&gt; result.Size ==“XL”);

注意:我有点把这段代码写下来,但你明白了。我在Lucene的索引上使用了这个过程,在Sitecore中的结果高达700K +没有太多问题。祝你好运先生!

答案 3 :(得分:0)

啊!刚刚解决了分面搜索和CPU使用问题。这是一些边界线黑魔法编码和一些非常有创意的缓存。

我们找到了一种方法来实现Solr对Lucene的分面查询,男孩和男孩的结果非常快。

简短版本:

  • 构建一个保存在字典上的静态类。键:单个过滤器的唯一表示,值:由Lucene QueryFilter对象生成的BitArray。

    var queryFilter = new QueryFilter(filterBooleanQuery); var bits = queryFilter.Bits(indexReader); result [filter.ID.ToString()] = bits

  • 在后台异步定期构建此字典。我的大约80k文档的索引只需要大约15秒的时间来构建,但这足以让很多用户生气,所以以非阻塞的方式做这件事是至关重要的。

  • 使用按位逻辑查询此字典,以查找表示您正在查找的匹配项的结果BitArray。

    var combo =     facetDictionary [thisFilter.ID.ToString()]         。而(facetDictionary [selectedFilter.ID.ToString()]);

长版: http://www.devatwork.nl/articles/lucenenet/faceted-search-and-drill-down-lucenenet/

现在,我们的实现只是为了获得这些结果集的基数,但理论上你也可以使用这些位数组来获取索引中的实际文档。

祝你好运!

答案 4 :(得分:0)

升级到sitecore 7会为您提供开箱即用的方面。在一个漂亮的LINQ API中抽象,让你从Lucene和SOLR切换(其他人,比如ElasticSearch即将推出)......