Подтвердить что ты не робот

Внедрение Lucene в существующем стеке .NET/SQL Server с несколькими веб-серверами

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

  • Вы можете запросить его в общем доступе к файлу в любом случае, просто убедитесь, что только один индексирует за раз (write.lock, механизм блокировки каталога обеспечит это и ошибку при попытке сразу нескольких индексировщиков).
  • Помните, что мои заметки выше, это интенсивность ввода-вывода, когда много читателей летают вокруг, поэтому вам нужна широкая полоса пропускания в ваш магазин, за исключением, по крайней мере, iSCSI или оптоволоконной сети SAN, я был бы осторожен в этом подход к высокому трафику (сотни тысяч поисков в день).
  • Еще одно соображение заключается в том, как вы обновляете/предупреждаете свои веб-серверы (или какой-либо уровень запрашивает его). Когда вы закончите прохождение индексации, вам нужно будет снова открыть ваш IndexReader, чтобы получить обновленный индекс с новыми документами. Мы используем redis-канал обмена сообщениями, чтобы предупредить, кто бы ни заботился о том, что индекс обновлен... любой механизм обмена сообщениями будет работать здесь.

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

  • К сожалению, я не знаю об этом, но могу поделиться с вами тем, как я к этому обратился.
  • При индексировании определенной таблицы (аналогичной документу в Lucene) мы добавили rowversion в эту таблицу. Когда мы индексируем, мы выбираем исходя из последней строки rowversion (a timestamp типа datatype, отбрасываемого как BIGINT). Я решил сохранить последнюю индексную дату и последнюю индексированную rowversion в файловой системе через простой .txt файл по одной причине: все остальное в Lucene хранится там. Это означает, что если есть большая проблема, вы можете просто удалить папку, содержащую индекс, и следующий прогон индексации будет восстановлен и иметь полностью обновленный индекс, просто добавьте некоторый код, чтобы обрабатывать ничего, что означает "индексировать все",.

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

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

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

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