I’ve been investigating Azure Search with Sitecore’s new Azure App Service offering. I’ve got a giant Excel file of benchmarks and charts based on several permutations and configurations, and several other interesting tidbits that I need to organize into posts to this blog . . . so look for much more about this general topic in the future.
For now, I thought I’d share a point I’ve confirmed with Sitecore support regarding a limitation of Azure Search with Sitecore’s CloudSearchProviderIndex. The CloudSearchProviderIndex is what the standard Platform-As-A-Service product from Sitecore will use in place of Lucene or Solr or Coveo to power content search for Sitecore. This is the key building block for working with Azure Search through Sitecore. While I was performing performance benchmarks for search re-indexing with Sitecore, I noticed the Azure Search document count would drop to 0 and I’d see odd results from Sitecore requests that depended on the search index. This was classic “search index is being worked on, don’t rely on querying it until the work is done” behaviour. This was corrected several years ago through Sitecore’s addition of a SwitchOnRebuildLuceneIndex and equivalent for Solr . . . but there is no such equivalent for the CloudSearchProviderIndex used by Azure PaaS solutions. Essentially: Sitecore is using a single copy of search indexes for query and re-indexing operations, limiting the availability of search during maintenance work.
One could argue this may not be such a big deal because one may not rebuild Azure Search indexes with any frequency. I’m not sold on this argument, however, since the Sitecore projects I know will frequently perform re-indexing due to development changes to the schema, content synchronization demands, or just routine deployment standard practices.
Further complicating this issue is that my benchmarking for Azure Search re-indexing through Sitecore leaves a lot to be desired. It can be slow. This could make for an extended period of search index unavailability due to the CloudSearchProviderIndex‘s limitations. I’ll share the full battery of testing I’ve done in a future post, but for now let me share the timings I’m observing regardless of the number of Azure Search partitions or replicas I’m working through (partitions should generally improve indexing performance; replicas should generally improve querying performance):
|App Service Configuration||Time for 20,000 Sitecore Items to Re-Index with Azure Search
|Azure PaaS Standard (S1) CM IIS (OOTB from the Marketplace)||66 minutes|
|Azure S2 CM IIS||35 minutes|
|Azure S3 CM IIS||25 minutes|
|Azure P2 CM IIS||35 minutes|
|Azure P3 CM IIS||24 minutes|
For reference, with Lucene indexes this operation would take 5 minutes or less. The scaling options for Azure Search, Partition count and Replica count, have a minimal impact to the re-indexing operation.
I’ll go into details of this later, but it could be that . . .
- 20,000 Sitecore items is too small a figure to benefit from scaling with Azure Search? Many customers have 100,000 or more items, so perhaps I should evaluate a larger data set.
- there are bottlenecks at the SQL tier? App Insights here I come…
- the fact Sitecore isn’t using Azure Search Indexers to ingest data and relies on the Sitecore crawling logic to handle data indexing is artificially slowing this process down
For the time being, Sitecore has responded that improving the availability of Azure Search indexes during rebuilds is an official “feature request” and assigned reference number 146822.
In the meantime, if a project needs high availability for Azure Search indexes one may need to roll up their sleeves and craft their own SwitchOnCloudSearchProviderIndex. It appears fairly straight-forward based on reviewing how this is solved for Solr, just as one example. A key caveat is in the Azure Search capacity planning documentation:
High availability for Azure Search pertains to queries and index updates that don’t involve rebuilding an index. If you add or delete a field, change a data type, or rename a field, you will need to rebuild the index. To rebuild the index, you must delete the index, re-create the index, and reload the data.
To maintain index availability during a rebuild, you must have a copy of the index with a different name on the same service, or a copy of the index with the same name on a different service, and then provide redirection or failover logic in your code.
It looks like providing for high availability would double the price of Azure Search indexes, so there are a cascade of complications related to this.
My investigations into Sitecore and Azure Search yielded this complication — it’s not insurmountable, and I actually find it fascinating how an on-premises product (classic Sitecore) will evolve into a cloud-first product. This is just one piece of the evolutionary story. I expect this will be addressed sooner rather than later in an official upgrade or patch from Sitecore, and until then it’s important to understand this nuance to the Sitecore PaaS landscape.