contact@skillcore.net

Using SwitchOnRebuildSolrSearchIndex Solr provider for Sitecore

Posted 5 October 2014 by Marek Musielak

sitecore and solr - custom field reader and indexing

Few days ago a colleague of mine, Dave, asked me why we hadn't been using SwitchOnRebuildSolrSearchIndex Solr provider in our Sitecore solution. I've heard about SwitchOnRebuild provider for Lucene but never about Solr one and neither had at that time Google. But SwitchOnRebuildSolrSearchIndex class exists so someone must know something. I asked about it on twitter. 13 minutes later Martina Welander replied to my tweet and one hour later I've received an email with documentation.

Post below is based on the Sitecore 7.5 documentation section written by Stephen Pope but was tested on Sitecore 7.2 rev 140526 and Solr 4.7.2. If you need an introduction on how to configure Solr with Sitecore, watch Sitecore SOLR Flair video.

What SwitchOnRebuildSolrSearchIndex provider gives you?

Lets assume that your Sitecore solution uses Solr as its search provider. When you rebuild indexes from Indexing Manager application or programmatically, you'll not get any results from the Solr server during the time indexes are being rebuilt. This is where SwitchOnRebuildSolrSearchIndex can help you. It adds a capability of handling two cores for any of your Sitecore indexes. This means that when you start rebuilding index, Sitecore will still return results using one of the Solr cores, while the other core will be rebuilt. And after the core is rebuilt, Sitecore will switch the cores and will use rebuilt core to serve search results.

How to duplicate a Solr index?

This depends a little bit on the version of Solr you use. Sitecore documentation is written assuming that you use Solr 4.1.0 while I use Solr 4.7.2. In both versions you need to go to the Solr server files, find the itembuckets core directory and create a copy of it called itembuckets_sec.

For Solr 4.1.0 you need to edit solr.xml file like this:

<cores defaultCoreName="itembuckets" adminPath="/admin/cores" 
    zkClientTimeout="${zkClientTimeout:15000}" hostPort="8983" hostContext="solr">
  <core loadOnStartup="true" instanceDir="itembuckets\" 
                             transient="false" name="itembuckets"/>
  <core loadOnStartup="true" instanceDir="itembuckets_sec\" 
                             transient="false" name="itembuckets_temp"/>
</cores>

In Solr 4.7.2 you need to edit core.properties file in itembuckets_sec directory and set the name of the new core like this:
name=itembuckets_sec.

Now you need to restart Solr server and check if both Solr cores work by testing if the urls below return Solr response XML:
http://localhost:8983/solr/itembuckets/select/?q=*:*&version=2.2
http://localhost:8983/solr/itembuckets_sec/select/?q=*:*&version=2.2

How to configure Sitecore to work with 2 Solr cores for a particular index

The only thing you need to do is to update chosen index configuration. Open Sitecore.ContentSearch.Solr.Indexes.config from App_Config\Include directory, find the index configuration, replace Sitecore.ContentSearch.SolrProvider.SolrSearchIndex with Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex and add another parameter <param desc="rebuildcore">itembuckets_sec</param>, e.g. if you want to configure sitecore_master_index index:

<index id="sitecore_master_index" 
  type="Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex, Sitecore.ContentSearch.SolrProvider">
    <param desc="name">$(id)</param>
    <param desc="core">itembuckets</param>
    <param desc="rebuildcore">itembuckets_sec</param>
    <param desc="propertyStore" ref="contentSearch/databasePropertyStore" param1="$(id)" />
    <configuration ref="contentSearch/indexConfigurations/defaultSolrIndexConfiguration" />
    <strategies hint="list:AddStrategy">
      <strategy ref="contentSearch/indexUpdateStrategies/sync" />
    </strategies>
    <locations hint="list:AddCrawler">
      <crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
        <Database>master</Database>
        <Root>/sitecore</Root>
      </crawler>
    </locations>
</index>

So how does it work?

When Sitecore is configured to use 2 cores for particular index, it will use the primary one for retrieving search results. Every time you execute rebuild of the index, secondary core will be rebuilt and after the rebuild, cores will be switched - the rebuilt core will become new primary core, and the old primary core will become secondary core now.

Thanks for reading my blog post. If you have any comments or question, you can find me on twitter or send me an email. You may also be interested in my other blog post about Solr custom field reader and indexing in Sitecore.