Реализация Lucene на существующем стеке .NET / SQL Server с несколькими веб-серверами - PullRequest
28 голосов
/ 30 июня 2011

Я хочу взглянуть на использование Lucene для решения полнотекстового поиска для сайта, которым я в данный момент управляю.Сайт полностью построен на технологиях SQL Server 2008 / C # .NET 4.Данные, которые я просматриваю для индексации, на самом деле довольно просты: всего пара полей на запись и только одно из этих полей действительно доступно для поиска.

Мне не ясно, какой набор инструментов мне нужно использовать лучше всего.или какая архитектура мне нужна.В частности:

  1. Куда мне поместить индекс?Я видел, как люди рекомендуют размещать его на веб-сервере, но это может показаться расточительным для большого количества веб-серверов.Конечно, лучше было бы централизовать здесь?

  2. Если индекс централизован, как бы я его запросил, учитывая, что он просто живет в файловой системе?Придется ли мне эффективно размещать его на общем сетевом ресурсе, который могут видеть все веб-серверы?

  3. Существуют ли какие-либо ранее существующие инструменты, которые будут постепенно заполнять индекс Lucene по расписанию, вытягиваяданные из базы данных SQL Server?Будет ли мне лучше развернуть здесь свой собственный сервис?

  4. Когда я запрашиваю индекс, я должен просто попытаться получить обратно несколько идентификаторов записей, которые я затем возвращаю в БДдля фактической записи, или я должен стремиться вытянуть все, что мне нужно для поиска, прямо из индекса?

  5. Есть ли смысл пытаться реализовать что-то вроде Solr в этой среде со вкусом?Если это так, я бы, вероятно, предоставил ей собственную * nix VM и запустил бы ее в Tomcat.Но я не уверен, что Солр купит меня в этом случае.

1 Ответ

50 голосов
/ 30 июня 2011

Я немного отвечу, основываясь на том, как мы решили реализовать Lucene.Net здесь, на Stack Overflow , и на некоторых уроках, которые я усвоил на этом пути:

Где следуетЯ поставил индекс?Я видел, как люди рекомендуют размещать его на веб-сервере, но это может показаться расточительным для большого количества веб-серверов.Конечно, централизация была бы лучше здесь?

  • Это зависит от ваших целей здесь, у нас был сильно недостаточно используемый веб-уровень (~ 10% ЦП) иперегруженная база данных, выполняющая полнотекстовый поиск (около 60% ЦП, мы хотели, чтобы она была ниже).Загрузка одного и того же индекса на каждый веб-уровень позволяет нам использовать эти машины и иметь тонну избыточности , мы все равно можем потерять 9 из 10 веб-серверов и поддерживать сеть Stack Exchange в рабочем состоянии.если нужно.В этом есть и обратная сторона, для нас это очень интенсивный ввод-вывод (чтение), и веб-уровень не был куплен с учетом этого (это часто бывает в большинстве компаний).Хотя он работает нормально, мы все равно будем обновлять наш веб-уровень до твердотельных накопителей и реализовывать некоторые другие биты, оставленные вне порта .Net, чтобы компенсировать этот аппаратный недостаток (например, NIOFSDirectory).
  • Другойнедостаток, если мы индексируем все наши базы данных n раз для веб-уровня, но, к счастью, у нас нет недостатка в пропускной способности сети и кэшировании результатов SQL-сервера, что делает эту операцию очень быстрой дельта-индексации каждый раз.С большим количеством веб-серверов это само по себе может исключить эту опцию.

Если индекс централизован, как бы я запросил его, учитывая, что он просто живет в файловой системе?Придется ли мне эффективно размещать его на общем сетевом ресурсе, который могут видеть все веб-серверы?

  • Вы можете запросить его на общем ресурсе в любом случае, просто убедитесь, что только один индексирует навремя (write.lock, механизм блокировки каталогов обеспечит это и выдает ошибку при попытке одновременно использовать несколько IndexWriters).
  • Имейте в виду мои заметки выше, это интенсивный ввод-вывод, когда много читателей летают вокругТаким образом, вам нужна достаточная пропускная способность для вашего магазина, за исключением, по крайней мере, iSCSI или оптоволоконной сети хранения данных. Я бы с осторожностью отнесся к этому подходу при использовании большого трафика (сотни тысяч запросов в день).
  • ДругойРассматривается вопрос о том, как вы обновляете / оповещаете свои веб-серверы (или любой другой уровень, запрашивающий его).Когда вы закончите проход индексации, вам нужно будет заново открыть IndexReader s, чтобы получить обновленный индекс с новыми документами.Мы используем канал сообщений Redis , чтобы предупредить всех, кто заботится об обновлении индекса ... здесь будет работать любой механизм обмена сообщениями.

Существуют ли уже существующие инструментычто будет постепенно заполнять индекс Lucene по расписанию, извлекая данные из базы данных SQL Server?Не лучше ли мне развернуть здесь свое собственное служение?

  • К сожалению, я не знаю ни одного из них, но могу поделиться с вами тем, как я к этому подошел.
  • КогдаИндексируя конкретную таблицу (похожую на документ в Lucene), мы добавили rowversion к этой таблице.Когда мы индексируем, мы выбираем на основе последней версии строки ( отметка времени тип данных, возвращаемая как bigint ).Я решил сохранить последнюю дату индекса и последнюю индексированную версию строки в файловой системе через простой файл .txt по одной причине: все остальное в Lucene хранится там.Это означает, что если когда-либо возникнет большая проблема, вы можете просто удалить папку, содержащую индекс, и следующий проход индексации восстановится и будет иметь полностью обновленный индекс, просто добавьте некоторый код, который не обрабатывает ничего, что означает «индексировать все».

Когда я запрашиваю индекс, стоит ли мне просто собирать кучу идентификаторов записей, которые я затем возвращаю в БД для фактической записи, или я должен стремитьсявытащить все необходимое для поиска прямо из индекса?

  • Это на самом деле зависит от ваших данных, для нас не очень реально хранить все в индексе (и это не рекомендуется). Я предлагаю вам сохранить поля для результатов поиска в индексе, и под этим я подразумеваю то, что вам нужно представить результаты поиска в списке, прежде чем пользователь щелкнет, чтобы перейти к полному [вставить введите здесь].
  • Другое соображение - как часто ваши данные меняются. Если многие поля, которые вы не ищите, быстро меняются, вам нужно будет переиндексировать эти строки (документы), чтобы обновить индекс, а не только когда поле, в котором вы ищите изменения .

Есть ли смысл пытаться реализовать что-то вроде Solr в этой среде со вкусом? Если это так, я бы, вероятно, предоставил ей собственную * nix VM и запустил бы ее в Tomcat. Но я не уверен, что Солр купит меня в этом случае.

  • Конечно, это централизованный поиск, о котором вы говорите (при большом количестве поисков вы можете снова достичь предела при настройке виртуальной машины, следите за этим). Мы этого не сделали, потому что это внесло (как нам кажется) большую необоснованную сложность в наш технологический стек и процесс сборки, но для большего числа веб-серверов это делает намного больше смысла.
  • Что он тебе покупает? производительность в основном и выделенный сервер (ы) индексирования. Вместо серверов n, просматривающих общий сетевой ресурс (также конкурирующих за ввод-вывод), они могут подключиться к одному серверу, который только обрабатывает запросы и результаты по сети, не сканируя индекс, что намного больше данные идут туда-сюда ... это будет локально на серверах Solr. Кроме того, вы не слишком часто обращаетесь к своему SQL-серверу, так как индексируется меньше серверов.
  • То, что он не покупает, - это такая же избыточность, но вам решать, насколько это важно. Если вы можете нормально работать с ухудшенным поиском или без него, просто сделайте это в своем приложении. Если вы не можете , то резервный сервер Solr или более может также быть допустимым решением ... и возможно сохранение другого программного стека.
...