Волшебной пули нет.
Поиск каждого осколка подряд исключен, очевидно, из-за невероятно высокой задержки, которую вы понесете.
Так что вы хотите искать параллельно, если вам нужно.
Есть два реалистичных варианта, и вы уже перечислили их - индексирование и параллельный поиск. Позвольте мне немного подробнее рассказать о том, как вы будете их проектировать.
Основное понимание, которое вы можете использовать, заключается в том, что при поиске вам редко требуется полный набор результатов. Вам нужна только первая (или n-я) страница результатов. Таким образом, есть достаточно места для маневра, чтобы уменьшить время отклика.
Индексация
Если вам известны атрибуты, по которым будут выполняться поиск пользователей, вы можете создать собственные, отдельные индексы для них. Вы можете создать свой собственный инвертированный индекс , который будет указывать на кортеж (shard, recordId) для каждого поискового запроса, или вы можете сохранить его в базе данных. Обновлять его лениво и асинхронно. Я не знаю требований к вашему приложению, возможно, даже можно будет перестраивать индекс каждую ночь (это означает, что у вас не будет самых последних записей в любой день - но это может подойти вам). Обязательно оптимизируйте этот индекс по размеру, чтобы он мог поместиться в памяти; обратите внимание, что вы можете осквернить этот индекс, если вам нужно.
Естественно, если люди могут искать что-то вроде "lastname='Smith' OR lastname='Jones'"
, вы можете прочитать индекс Смита, прочитать индекс Джоунса и вычислить объединение - вам не нужно хранить все возможные запросы, только их составные части. .
Параллельный поиск
Для каждого запроса отправляйте запросы каждому фрагменту, если вы не знаете, какой фрагмент искать, потому что поиск происходит по ключу распределения. Сделайте запросы асинхронными. Ответить пользователю, как только вы получите первую страницу результатов; соберите все остальное и кешируйте локально, так что если пользователь нажмет «следующий», вы будете иметь готовые результаты, и вам не нужно будет повторно запрашивать серверы. Таким образом, если для некоторых серверов требуется больше времени, чем для других, вам не нужно ждать на них для обслуживания запроса.
Пока вы это делаете, регистрируйте время отклика защищенных серверов, чтобы увидеть потенциальные проблемы с неравномерным распределением данных и / или нагрузки.