diff --git a/src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php b/src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php --- a/src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php +++ b/src/applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php @@ -303,7 +303,8 @@ $exceptions[] = $e; } } - throw new PhutilAggregateException('All search hosts failed:', $exceptions); + throw new PhutilAggregateException(pht('All Fulltext Search hosts failed:'), + $exceptions); } public function indexExists(PhabricatorElasticSearchHost $host = null) { diff --git a/src/docs/user/cluster/cluster.diviner b/src/docs/user/cluster/cluster.diviner --- a/src/docs/user/cluster/cluster.diviner +++ b/src/docs/user/cluster/cluster.diviner @@ -47,6 +47,7 @@ | **SSH Servers** | Minimal | Low | No Risk | Low | **Web Servers** | Minimal | **High** | No Risk | Moderate | **Notifications** | Minimal | Low | No Risk | Low +| **Fulltext Search** | Moderate | **High** | Minimal Risk | Moderate See below for a walkthrough of these services in greater detail. @@ -237,6 +238,33 @@ For details, see @{article:Cluster: Notifications}. +Cluster: Fulltext Search +======================== + +At a certain scale, you may begin to bump up against the limitations of MySQL's +built-in fulltext search capabilities. We have seen this with very large +installations with several million objects in the database and very many +simultaneous requests. At this point you may consider adding Elasticsearch +hosts to your cluster to reduce the load on your MySQL hosts. + +Elasticsearch has the ability to spread the load across multiple hosts and can +handle very large indexes by sharding. + +Search does not involve any risk of data lost because it's always possible to +rebuild the search index from the original database objects. This process can +be very time consuming, however, especially when the database grows very large. + +With multiple Elasticsearch hosts, you can survive the loss of a single host +with minimal disruption as Phabricator will detect the problem and direct +queries to one of the remaining hosts. + +Phabricator supports writing to multiple indexing servers. This Simplifies +Elasticsearch upgrades and makes it possible to recover more quickly from +problems with the search index. + +For details, see @{article:Cluster: Search}. + + Overlaying Services =================== diff --git a/src/infrastructure/cluster/search/PhabricatorSearchService.php b/src/infrastructure/cluster/search/PhabricatorSearchService.php --- a/src/infrastructure/cluster/search/PhabricatorSearchService.php +++ b/src/infrastructure/cluster/search/PhabricatorSearchService.php @@ -235,21 +235,20 @@ * @throws PhutilAggregateException */ public static function executeSearch(PhabricatorSavedQuery $query) { - $services = self::getAllServices(); $exceptions = array(); - foreach ($services as $service) { - $engine = $service->getEngine(); - // try all hosts until one succeeds + // try all services until one succeeds + foreach (self::getAllServices() as $service) { try { + $engine = $service->getEngine(); $res = $engine->executeSearch($query); - // return immediately if we get results without an exception + // return immediately if we get results return $res; } catch (Exception $ex) { $exceptions[] = $ex; } } - throw new PhutilAggregateException('All search engines failed:', - $exceptions); + $msg = pht('All of the configured Fulltext Search services failed.'); + throw new PhutilAggregateException($msg, $exceptions); } }