Federating People Search results from a separate Search Service Application
The introduction of service applications in SharePoint 2010 created a wide range of possibilities for centralizing “common” services. If you ever tried to consume multiple search service applications (SSAs) in 2010, though, you probably quickly realized that there were some “gotchas”. This post will provide a scenario in which it is beneficial to use a separate SSA for crawling People/My Sites (“social”) content, the options/limitations in SharePoint Search 2010, and the improvements in SharePoint Search 2013 that overcome the 2010 limitations.
First, let’s lay out a scenario where you might want to have a separate SSA for “social” content. In this scenario, we are going to have a large number of user profiles and each user will be allowed to have a My Site. The user profiles will be common across all of our farms, so we want to centralize all things related to user profiles (i.e. – a centralized UPA, centralized “social” search, etc.). However, our “content” SSAs will reside in a variety of other places (maybe “common” SSAs or SSAs that are specific to certain farms. We don’t want multiple SSAs attempting to crawl the user profile data due to the impact on the network and the user profile store (i.e.- we want to crawl “social” content once and consume many times). Now let’s look at the options we had in SharePoint Search 2010 and what we get with SharePoint Search 2013.
It was possible to create numerous SSAs and attach them to a single web application. This might have led you to believe (understandably so) that SharePoint would pass your user’s query to each of the SSAs, combine the results, and present a results set that represented the matches from each attached SSA. Unfortunately, SharePoint simply used the “default” SSA and ignored the others. This behavior is unchanged in SharePoint Search 2013. In 2010, you could have used federation to integrate content from other search indices and this worked fairly seamlessly if you were dealing with “normal” content. But what if you were dealing with People content? Federation in SharePoint Search 2010 provided results in an RSS form, which severely limited the data that was returned for People content and provided a result set that looked nothing like SharePoint’s People results. Unless you wanted to write an extensive amount of custom code, you were stuck with either crawling People content from the same SSA that crawled your content or with a less-than-appealing results set for People content.
SharePoint Search 2013 introduces the concept of a “Remote SharePoint” result source. So how is this different than the federation option in SharePoint Search 2010? Glad you asked. The “Remote SharePoint” result source allows you to pass your query to the remote service and get a full-fidelity result set. This means you lose none of the People search “goodness” that comes from having People content crawled by your local SSA. Go ahead, applaud. The configuration of the inter-farm trust relationship that this requires is not simple, but has been laid out nicely by Steve Peschka in this post about oAuth trust between farms. In my scenario, I created a site collection based on the “Enterprise Search Center” template in my “common” farm and used that URL in my configuration of the “Remote SharePoint” result source. The only issue I encountered was with Step 4. I was getting errors stating that it could not find the app principal. After checking/reconfiguring the trust numerous times, it finally occurred to me that the “App Management Service” (in “Services on Server”) needed to be started on the “common” farm from which I wanted to consume the remote index. As soon as I started that service, Step 4 completed successfully and my remote People content began appearing in my search center. The other thing to what out for if you are building this scenario in a resource constrained test lab, is that services such as the security token service in SharePoint 2013 will not start if the server is under memory pressure (by default, it must have more than 5% free memory). This can be changed by adding the “minFreeMemoryPercentageToActivateService” attribute in the service’s web.config file (NOTE: Only do this in a dev/test environment. If you are encountering memory pressure in Production, address that by reducing load or adding memory).