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

Синхронизация индексов Lucene.net на нескольких серверах приложений

мы разрабатываем архитектуру поиска для корпоративного веб-приложения. Для этого мы будем использовать Lucene.net. Индексы не будут большими (около 100 000 документов), но служба поиска всегда должна быть всегда и всегда быть актуальной. В индекс будут добавлены новые документы и одновременный поиск. Поскольку у нас должна быть высокая доступность для поисковой системы, у нас есть 2 сервера приложений, которые предоставляют службу WCF для выполнения поиска и индексирования (копия службы выполняется на каждом сервере). Затем сервер использует lucene.net API для доступа к индексам.

Проблема в том, что было бы лучшим решением для постоянного поддержания индексов? Мы рассмотрели несколько вариантов:

  • Использование одного сервера для индексирования и наличие второго сервера для доступа к индексы через SMB: нет, потому что мы иметь единственную точку отказа ситуация;

  • Индексирование на оба сервера, по существу, запись каждого индекса дважды: возможно, отвратительная производительность и возможность desync, если, например. индексы сервера 1 ОК и сервер 2 исчерпывает дисковое пространство или что-то еще,

  • Использование SOLR или KATTA для переноса доступа к индексам: нет, мы не можем иметь tomcat или аналогичный запуск на серверах, у нас есть только IIS.

  • Сохранение индекса в базе данных: я нашел, что это можно сделать с помощью java-версии Lucene (модуль JdbcDirectory), но я не нашел ничего подобного для Lucene.net. Даже если это означало небольшой удар производительности, мы пошли бы на эту опцию, потому что это решило бы решить проблему concurrency и синхронизации с мини-разработкой.

  • Использование Lucene.net DistributedSearch Contrib module: я не смог зарегистрировать одну ссылку с документацией об этом. Я даже не знаю, просматривая код, что делает этот код, но мне кажется, что он фактически разбивает индекс на несколько машин, чего мы не хотим.

  • rsync и друзья, копируя индексы назад и вперед между двумя серверами: это кажется хакерским и подверженным ошибкам нам, и, если индексы становятся большими, может занять некоторое время, и в течение этого периода мы будем возвращать коррумпированные или несогласованные данные клиентам, поэтому нам нужно разработать специальную политику блокировки, которую мы не хотим.

Я понимаю, что это сложная проблема, но я уверен, что перед этим столкнулись многие люди. Любая помощь приветствуется!

4b9b3361

Ответ 1

Кажется, что лучшим решением было бы проиндексировать документы на обоих серверах в свою собственную копию индекса.

Если вы беспокоитесь о том, что индексирование будет продолжаться на одном сервере и не сработает на другом, вам нужно будет отслеживать успех/сбой для каждого сервера, чтобы вы могли повторно использовать неудавшиеся документы, когда проблема решена. Это отслеживание будет сделано за пределами Lucene в любой системе, которую вы используете, чтобы представить документы для индексации Lucene. В зависимости от того, насколько важна полнота индекса для вас, вам также может потребоваться удалить сбойный сервер из любого используемого балансировочного устройства нагрузки, пока проблема не будет устранена, а индексирование переработало любые выдающиеся документы.

Ответ 2

+1 для ответа Шона Карпентера. Индексирование на обоих серверах кажется самым безопасным и безопасным выбором.

Если индексируемые документы сложны (Word/PDF и их сортировки), вы можете выполнить некоторую предварительную обработку на одном сервере, а затем предоставить это серверам индексирования, чтобы сохранить некоторое время обработки.

Решение, которое я использовал ранее, предполагает создание блока индексов на одном сервере, затем rsync переход на серверы поиска и объединение блока в каждый индекс с помощью IndexWriter.AddIndexesNoOptimize. Вы можете создать новый кусок каждые 5 минут или всякий раз, когда он достигнет определенного размера. Если вам не нужно иметь абсолютно свежие индексы, это может быть для вас решением.

Ответ 3

в java-мире, мы решили эту проблему, поставив MQ перед индексом (es). Вставка была завершена только тогда, когда bean вытащил из очереди успешно, иначе он просто отбросил все действия, которые потребовались, помеченные в документе как ожидающие, и снова попытался выполнить его

Ответ 4

Я знаю, что это старый вопрос, но я просто наткнулся на него и хотел дать 2 цента для тех, кто ищет советы по многосерверной реализации.

Почему бы не сохранить файлы индекса в общей папке NAS? Как это отличается от хранения индекса в базе данных, которую вы рассматривали? База данных может быть реплицирована для высокой доступности, и поэтому может быть NAS!

Я бы настроил два сервера приложений, которые у вас есть за балансировщиком нагрузки. Любой запрос индекса, который входит, будет индексировать документы в отдельной папке компьютера на NAS. То есть на NAS будет столько индексов, сколько серверов приложений. Когда приходит запрос на поиск, вы будете выполнять поиск по нескольким индексам с использованием Lucene. У Lucene есть встроенные конструкторы (MultiSearcher), и производительность по-прежнему отличная.

Ответ 5

Как мы храним наши балансированные нагрузки серверы синхронно, каждый со своей собственной копией Lucene, должен иметь задачу на каком-то другом сервере, который каждые 5 минут запускает каждый сервер с балансировкой нагрузки, чтобы обновить свой индекс до определенная метка времени.

Например, задача отправляет отметку времени "12/1/2013 12: 35: 02.423" всем серверам с балансировкой нагрузки (задача отправляет временную метку с помощью запроса на веб-страницу на каждом балансировочном веб-сайте), то каждый сервер использует эту метку времени для запроса базы данных для всех обновлений, которые произошли с момента последнего обновления до этой метки времени, и обновляет свой локальный индекс Lucene.

Каждый сервер также сохраняет временную метку в db, поэтому он знает, когда последний сервер обновлялся. Поэтому, если сервер отключается, когда он возвращается в сеть, в следующий раз, когда он получает команду timestamp, он будет захватывать все обновления, которые он пропустил, когда он был в автономном режиме.